工厂函数和构造函数
工厂函数
工厂模式是一种设计模式,说白了就是一种简单的函数,这个函数可以创建对象,为它添加属性和方法,然后返回这个对象。就像一个工厂一样,可以批量制作某种类型的对象。这种设计模式是就是为了降低代码冗余。
简单写一个小例子
这里函数 createPerson()接收俩个参数,根据这几个参数构建了一个包含 person 信息的对象。这样写主要是为了解决需要创建大量有属性重叠的对象,如果每个都 new 一下,然后逐一添加属性。这也是个累人的活。通过上面的代码中,我们声明了一个 createPerson 方法,此方法可批量制造。但是还有缺点,它没有解决对象标识问题(就是创建的对象是什么类型)。
构造函数
构造函数模式可以自定义引用类型,可以使用 new 关键字创建内置类型实例应用创建自定义类型实例,我们常用的 new Vue(),其本质上就是传递 options 参数,实例化一个 Vue 对象。
上面的工厂函数我们可以用构造函数来改进一下
在这个例子中,我们可以发现构造函数可以替代工厂函数,在实际开发中,我们用构造函数的频率一般会大于用工厂函数的频率。
注意:按照惯例,构造函数名称的首字母要大写
要创建 Person 的新实例,必须使用 new 操作符。以这种方式调用构造函数,实际上会有以下 5 个步骤。
(1) 在内存中创建一个新对象。
(2) 这个新对象内部的 Prototype 特性被赋值为构造函数的 prototype 属性。
(3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
(4) 执行构造函数内部的代码(给新对象添加属性)。
(5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
构造函数虽然好用,但是也有一些问题,我们分析一下逻辑
上面的例子,person1 和 person2 都有一个 sayName()方法,但这俩个方法却不是同一个 function 实例,相当于这里定义的方法 sayName()会在每个实例上都创建一遍,虽然我们自己省事了,但机器可不省事。
优化一下
因为做的事情是一样的,所以没必要定义俩个不同的 Function 实例,我们可以把函数定义转移到构造函数外部。
在这里,sayName()被定义在了构造函数外部。在构造函数内部,sayName 属性等于全局 sayName() 函数。因为这一次 sayName 属性中包含的只是一个指向外部函数的指针,所以 person1 和 person2 共享了定义在全局作用域上的 sayName()函数。这样虽然解决了相同逻辑的函数重复定义的问题,但全局作用域也因此被搞乱了,因为那个函数实际上只能在一个对象上调用。如果这个对象需要多个方法,那么就要在全局作用域中定义多个函数。这会导致自定义类型引用的代码不能很好地聚集一起。这个新问题可以通过原型模式来解决。
版权声明: 本文为 InfoQ 作者【大熊G】的原创文章。
原文链接:【http://xie.infoq.cn/article/9acda9361f9bca5a3f1a69fc3】。文章转载请联系作者。
评论