function SpecialArray(){ var values = new Array(); values.push.apply(values, arguments); values.toPipedString = function(){ return this.join("|"); }; return values; } var colors = new SpecialArray("red", "blue", "green"); alert(colors.toPipedString()); //"red|blue|green"
关于javascript中的寄生构造函数模式,我觉得他和工厂模式其实就是一样的,只不过在写法上用了new这种构造函数的写法,用意是要在不扩展原生构造函数的情况下自定义一个扩展型的构造函数。
既然是扩展原生的构造函数,那么用起来当然要像个构造函数,于是就用了new这种构造函数的写法。显式的return重写了调用构造函数时返回的值,所以new不new其实最后的结果没有影响,那么写只是为了用起来像构造函数。
之所以要有这个模式是因为构造函数模式只能new出一个Object类型,不能够new出一个比如Array,类似这样是行不通的:
function SpecialArray(){ this = new Array(); this.push.apply(this, arguments); this.toPipedString = function(){ return this.join("|"); }; } var colors = new SpecialArray("red", "blue", "green"); alert(colors.toPipedString());//报错:Invalid left-hand side in assignment
大家看看我理解的对吗?
ringa_lee2017-04-10 12:50:09
书上原话:除了使用new操作符并把使用的的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。构造函数在不返回值的情况下。默认会返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。
伊谢尔伦2017-04-10 12:50:09
很好的问题。
我不知道“寄生构造函数”这个说法呢。理论学习有些落伍了。
谈谈我的实践经验吧。
首先,你不能修改 this
。它是只读的保留字(keyword),跟for
、while
是一个级别的。
其次,你可以在构造函数最后返回任意一个对象。它将代替this!
如果你不考虑继承,那么单个类你可以这样创建:
function SpecialArray(){
o = new Array();
o.push.apply(o, arguments);
o.toPipedString = function(){
return this.join("|");
};
return o;
}
var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString());
注:如果你写 CoffeeScript ,那么你会发现在 正常 的构造函数最后,往往必须以@结尾,否则CoffeeScript会把最后一行代码的表达式值(可能是任何东西)作为构造函数的返回值,然后就出错了……
但如果你要“原装”的继承机制,那么还需要考虑构造函数对应的 prototype 链。这样问题就复杂起来。
我已有一套比较好的机制,但还不够成熟。
巴扎黑2017-04-10 12:50:09
这个new 不 new SpecialArray,其结果都是一样的,劝不要自行意象,容易理解出错。
具体和工厂模式的区别,不甚了解。
不过后面也说了一下, 这个constructor和prototype是没有联系的。
this = new Array(); 这个是错的。