工厂模式,构造器模式和原型模式的区别_情节的结构模式有哪些

工厂模式,构造器模式和原型模式的区别_情节的结构模式有哪些工厂模式,构造函数模式(寄生构造函数模式,稳妥构造函数模式,作用域安全的构造函数模式),原型模式(动态原型模式)

工厂模式,构造器模式和原型模式"

一、工厂模式

工厂模式属于创建型模式,它提供了一种创建对象的最佳方式。我们在函数内部创建一个对象,赋予对象属性和方法,并通过return返回这个对象

function createPerson(name, age, job) {
    var o = new Object()
    o.name = name
    o.age = age
    o.job = job
    o.sayName = function() {
      console.log(this.name)
    }
    return o
  }
  var person1 = createPerson('caoyuan', 25, 'Software engineer')
  var person2 = createPerson('neil', 23, 'Software engineer')
  console.log(person1) // {name: "caoyuan", age: 25, job: "Software engineer", sayName: ƒ}
  console.log(person2) // {name: "neil", age: 23, job: "Software engineer", sayName: ƒ}

二、构造函数模式

构造模式和工厂模式创建对象的不同点在于;

  1. 没有显式的创建对象
  2. 直接将属性和方法赋值给了this对象
  3. 没有return对象
function Person(name, age, job) {
    this.name = name
    this.age = age
    this.job = job
    this.sayName = function() {
      console.log(this.name)
    }
  }
  let person1 = new Person('caoyuan', 25, 'Software Engineer')
  let person2 = new Person('neil', 23, 'Software engineer')
  person1.sayName()
  person2.sayName()

以这种方式调用构造函数实际会经历一下四个步骤

  1. 创建一个对象
  2. 将构造函数的作用域赋给新对象(因此this就指向这个对象)
  3. 执行构造函数种的代码(为这个新对象添加属性)
  4. 返回对象

寄生构造函模式

这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装对象的代码,然后再返回新创建的对象。

function Person(name, age, job) {
    var o = new Object()
    o.name = name
    o.age = age
    o.job = job
    o.sayName = function() {
      console.log(this.name)
    }
    return o
  }
  let friend = new Person('neil', 25, 'software Engineer')
  friend.sayName() // neil

以上就是例子,把new操作符抛去,这个模式和工厂模式一模一样。构造函数在不返回值的情况下,默认会返回新对象实例,而通过构造函数的末尾添加一个return语句,可以重写调用给构造函数时返回的值。 如下例子

function SpecialArray () {
    // 创建数组
    var values = new Array()
    // 添加值
    values.push.apply(values, arguments)
    // 添加方法
    values.toPipedString = function() {
      return this.join('|')
    }

    // 返回数组
    return values

  }
  var color = new SpecialArray('1','2','3')
  console.log(color.toPipedString()) // 1|2|3

稳妥构造函数模式 稳妥对象是指没有公共属性, 方法也不引用this的对象。适合在安全的环境中,或者防止数据被其他应该改动时使用

稳妥模式遵循与寄生构造函数类似的模式,但 有两点不同;

  1. 创建新对象的实例不引用this;
  2. 不使用new操作符调用构造函数
function Person(name, age, job) {
    var o = new Object()
    o.sayName = function() {
      console.log(name)
    }
    return o
  }

  let person = Person('neil', 25, 'software Engineer')
  person.sayName() // neil

作用域安全的构造函数

通过代码介绍下作用域安全的构造函数
function Person(name, age, job) {
    this.name = name
    this.age = age
    this.job = job
  }
 var person = Person('neil', 25, 'Softwate Engineer')
 console.log(window.age) // 25

假设用上述这种方式调用,this指向window,那么值也就在window上了,那么怎么才能解决这种问题呢, 修改代码如下

function Person(name, age, job) {
    if (this instanceof Person) {
      this.name = name
      this.age = age
      this.job = job
    } else {
      return new Person(name, age, job)
    }
  }
  var person = Person('neil', 25, 'software Engineer')
  console.log(window.age) // undefined
  console.log(person.age) // 25

通过instanceof来判断当前this是否是person实例上的,现在看上去好像没有什么问题了,那么假设用了构造函数窃取模式的继承且不使用原型链,这个继承可能就被破坏了

function Polygon(sides) {
    if (this instanceof Polygon) {
      this.sides = sides
      this.getArea = function() {
        return 0
      }
    } else {
      return new Polygon(sides)
    }
  }

  function Rectangle(width, heigth) {
    Polygon.call(this, 2) 
    this.width = width
    this.heigth = heigth
    this.getArea = function () {
      return this.width * this.heigth
    }
  }
  let rect = new Rectangle(5, 10)
  console.log(rect.sides) // undefined

你会发现,rect.sides为undefined,为啥呢,Polygon这个实例是安全的,但是,Rectangle中是通过call来继承Polygon的sides属性,这是因为this对象不是Polygon的实例,所以创建了一个新的Polygon对象,Rectangle中并没有sides属性。如果构造函数窃取结合使用原型链和寄生模式就可以解决这个问题了,代码如下

function Polygon(sides) {
    if (this instanceof Polygon) {
      this.sides = sides
      this.getArea = function() {
        return 0
      }
    } else {
      return new Polygon(sides)
    }
  }

  function Rectangle(width, heigth) {
    Polygon.call(this, 2) 
    this.width = width
    this.heigth = heigth
    this.getArea = function () {
      return this.width * this.heigth
    }
  }
  Rectangle.prototype = new Polygon()
  let rect = new Rectangle(5, 10)
  console.log(rect.sides) // 2

三、原型模式

我们创建的每个函数都有prototype属性,这个属性是一个指针,指向对象,而这个对象包含可以由特定类型的所有实列共享的属性和方法。prototype就是通过调用构造函数而创建的那个实例对象的原型对象。

  function Person() {
  }
  Person.prototype.name = 'caoyuan'
  Person.prototype.age = '25'
  Person.prototype.sayName = function() {
    console.log(this.name)
  }
  let person1 = new Person()
  let person2 = new Person()
  person2.sayName()
  person1.sayName()
  console.log(person1.sayName == person2.sayName)

动态原型模式

它把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型,也保持了同时使用构造函数和原型的优点

function Person(name, age, job) {
    this.name = name
    this.age = age
    this.job = job
    // 方法
    if (typeof this.sayName != 'function') {
      Person.prototype.sayName = function() {
        console.log(this.name)
      }
    }
  }
  let person = new Person('neil', 25, 'Software Engineer')
  person.sayName()

四、组合使用构造函数模式和原型模式

创建自定义对象最常见的方式,就是组合使用构造函数模式和原型模式。

  1. 构造函数模式定义实例的属性
  2. 原型模式用于定义方法和共享的属性
function Person(name, age, job) {
  this.name = name
  this.age = age
  this.children = ['1', '2']
}
Person.prototype.sayName = function() {
  console.log(this.name)
}

let person1 = new Person('caoyuan', 25, 'Software Engineer')
let person2 = new Person('neil', 23, 'Software Engineer')

person1.children.push('3')
console.log(person1.children) // Array [1,2,3]
console.log(person2.children) // Array [1,2]
console.log(person1.children === person2.children) // false
console.log(person1.sayName === person2.sayName) // true

相关文章:

原型链基础及多种使用方式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13896.html

(0)

相关推荐

  • 利用Python求圆周率与平方根

    利用Python求圆周率与平方根圆周率是数学中一个广为人知的概念,也被称为圆周常数。在Python中,我们可以用多种方法来求圆周率。

    2023-12-08
    119
  • Python字典追加操作方法

    Python字典追加操作方法在Python中,字典是一种非常方便的数据类型,它可以用于存储键值对。字典的特点在于可以高效的找到一个键对应的值。Python中的字典是可变的,因此你可以向字典中添加或者删除元素,字典的追加操作是Python中使用频率非常高的操作之一。在本文中,我们将深入介绍Python字典追加操作方法,帮助开发者更好地理解和应用Python字典。

    2024-06-09
    52
  • Python tkinterpack基础入门

    Python tkinterpack基础入门如果你想学习Python GUI编程,那么Tkinter是一个非常好的选择。Tkinter作为Python内置的GUI工具包,其简易性、可移植性和可扩展性都是极为出色的。

    2024-06-13
    48
  • MySQL学习笔记(7):存储引擎[亲测有效]

    MySQL学习笔记(7):存储引擎[亲测有效]本文更新于2019-06-23,使用MySQL 5.7,操作系统为Deepin 15.4。 和大多数数据库不同,插件式存储引擎是MySQL最重要的特性之一。 InnoDB InnoDB表提供事务安全。

    2023-03-16
    138
  • Python和Py的区别及应用场景

    Python和Py的区别及应用场景Python是一门高级编程语言,被广泛应用于Web开发、数据科学、数字信号处理、自然语言处理等领域,Python解释器可以运行在多种操作系统上。Python语言具有高效的代码编写、易于维护、可扩展性好等特点,因此受到了广泛的应用。而Py则是Python在微型计算机(如微控制器)上的轻量级实现。

    2024-01-02
    115
  • 以Python输入为中心的原始标题

    以Python输入为中心的原始标题Python作为一门高级编程语言,在很多方面都具有很多优势,其中包括Python输入。Python输入就是指在程序运行时,程序能够从用户输入中获取所需要的数据。Python输入可以通过多种方式实现,其中包括直接通过input函数获取用户输入和读取文本文件中存储的数据等。

    2024-04-21
    64
  • 用Python实现正则表达式提取字符串信息

    用Python实现正则表达式提取字符串信息正则表达式是一种强大的工具,能够在文本中搜索、匹配和编辑特定的模式。Python内置了re模块,可以方便地使用正则表达式。在本文中,我们将介绍如何使用Python的re模块来提取字符串信息。

    2023-12-16
    104
  • Python中的实例变量和类变量

    Python中的实例变量和类变量在Python中,变量可以分为两种主要类型:实例变量和类变量。本文将详细介绍这两种变量类型以及它们的区别、优缺点和使用场景。

    2024-02-12
    98

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注