Javascript
中的组织函数与其他言语比拟也是差别的。任何经由过程关键字 new
挪用的函数都可以当作组织函数。
在组织函数体内,this
指向新建立的对象。假如组织函数体内没有显现的 return
表达式,那末我们就默许返回 this
,也就是新建的对象。
function Foo() {
this.bla = 1;
}
Foo.prototype.test = function() {
console.log(this.bla);
};
var test = new Foo();
上面的代码将 Foo
作为组织函数举行挪用,并将新建对象的原型(__proto__)
指向了 Foo.prototype
。
假如我们在组织函数内定义返回的 return
表达式,组织函数就会返回全部表达式,但这个返回表达式必需为一个对象。
function Bar() {
return 2;
}
new Bar(); // a new object
function Test() {
this.value = 2;
return {
foo: 1
};
}
new Test(); // the returned object
假如 new
被省略,那末函数将不能返回一个新的对象。
function Foo() {
this.bla = 1; // gets set on the global object
}
Foo(); // undefined
上面的例子能够在某些场景下也可以运转,但由于 Javascript
中 this
的事情机制,这里 this
将指向全局对象。
工场形式
为了可以不运用关键字 new
,组织函数将不得不显现返回一个值。
function Bar() {
var value = 1;
return {
method: function() {
return value;
}
}
}
Bar.prototype = {
foo: function() {}
};
new Bar();
Bar();
上例中使不运用 new
来挪用函数 Bar
到达的结果是一样的,将会返回一个新建的包括 method
要领的对象,这里实际上就是一个闭包。
这里须要注重一点,new Bar()
将不会返回 Bar.prototype
,而是在 return
表达式内函数 method
的原型对象。
上例中,运用 new
与否在功能上是无差别的。
经由过程工场形式建立新的对象
我们经常被提示不要运用 new
,由于一旦忘记了它的运用将致使毛病。
为了建立一个对象,我们更情愿运用工场形式并在工场形式内组织一个新的对象。
function Foo() {
var obj = {};
obj.value = 'blub';
var private = 2;
obj.someMethod = function(value) {
this.value = value;
}
obj.getPrivate = function() {
return private;
}
return obj;
}
只管上例代码比运用 new
时更不轻易失足,而且在运用私有变量时将越发轻易,但同时也有一些不好的处所:
- 由于不能同享原型对象,所以须要更多的内存。
- 为了完成继续,工场形式须要拷贝另一个对象的一切要领或许将其作为新对象的原型。
- 摒弃原型链只是为了防止运用
new
,这好像与Javascript
言语的精力相悖。
总结
只管运用 new
能够比较轻易发生毛病,但这并不能成为摒弃运用原型链的缘由。至于末了采用哪一种体式格局,这须要依据运用的需求而定。最好的体式格局就是挑选一种作风并坚持下去。
参考
http://bonsaiden.github.io/JavaScript-Garden/#function.constructors