看这两名字,都带构造函数,一个寄生一个稳妥。那么,先来回忆一下构造函数模式:
function Person (name, sex, age) {
this.name = name
this.sex = sex
this.age = age
this.sayName = function () {
console.log(this.name)
}
}
const p1 = new Person('windy-boy', 'male', '18')
console.log(p1) // Person {name: "windy-boy", sex: "male", age: "18", sayName: ƒ}
这就是构造函数模式,有不理解的可以翻翻这篇文章。接下来看下这两种模式是如何与构造函数搭上钩的。
寄生构造函数模式
看下例子:
function Person(name, sex, age) {
const person = new Object()
person.name = name
person.sex = sex
person.age = age
return person
}
const p1 = new Person('windy-boy', 'male', '18')
咋看之下,确实像构造函数模式,但仔细一看这个Person函数,这不是工厂模式吗?!好家伙,这是结合了工厂模式和构造函数模式就成了寄生构造函数模式了…
还记得构造函数模式new的作用吗?
- 创建一个对象
- 将this绑定到这个对象
- 往对象里面添加属性和方法
- 返回这个对象
但是,如果函数里面已经有返回对象了,那么这个对象就会覆盖掉new所返回的那个对象。那么问题来了,这个new在这里还有什么用呢??
来看一个例子:
function SpecialArray() {
var values = new Array()
values.push.apply(values, arguments)
values.toPipedString = function() {
console.log(this)
return this.join('|')
}
return values
}
var colors = new SpecialArray('red', 'blue', 'green')
console.log(colors.toPipedString(), 666)
var c = SpecialArray('red', 'blue', 'green')
console.log(c.toPipedString(), 999)
这个例子其实是高程里面的例子,我分别通过构造调用和直接调用两种方式来创建对象,并且都调用了里面的方法,可以看到,结果是完全一致的。这让我很纠结,感觉这个new在这里没有用了,有他没他都一样啊。
仔细翻看了高程里面的介绍,是这么说的:
通常,在前述几种模式都不适用的情况下,可以使用寄生构造函数模式
除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。
emmm,也就是说,这个模式就是在其他模式都不适用的情况下可以考虑使用。但是什么情况下其他模式会都不适用呢?暂时没有碰到这种情况,即使是书中提到的例子也就是上面的例子,也并非是在其他模式都不适用的情况下才这么写的。
综上,寄生构造函数模式我感觉就跟废了差不多,了解一下就行了。当然,如果有对这个模式更深入的理解以及非他不可的情况出现,望不吝在评论区留下见解。
稳妥构造函数模式
这是高程里面介绍的最后一种创建对象的模式了。
直接看例子:
function Person(name, age) {
const obj = new Object()
const height = 185
const eat = function() {
console.log('吃饭')
}
obj.sayName = function() {
console.log(name, age, height)
eat()
}
return obj
}
const p = Person('windy-boy', 18)
p.sayName()
这就是稳妥构造函数模式。就是对外暴露一个可以访问函数内部变量和方法的接口。只有通过这个接口才可以访问函数内部的变量和方法,其他方式都不行。这样的模式就是稳妥构造函数模式。
对比一下寄生构造函数模式,有两点不同:
- 没有this
- 没有new
其实我一直认为没有通过new调用的函数(也就是所谓的构造调用)就是普通函数,这里把函数名首字母大写来作为构造函数的标识,以这样的方式来和构造函数搭上钩。这是强行搭讪啊。。。个人感觉直接叫稳妥模式还好点。当然,这只是我的一点吐槽,发明这种模式的大师在命名的时候肯定有自己的考量,至于他的考量是什么,我也没有他电话,联系不到他,就不得而知了。。。
相比寄生构造函数模式,稳妥构造函数模式感觉更有机会用到。比如为了防止一些变量被意外更改,就可以使用稳妥构造函数模式。