Javascript 中的构造函数与其他语言相比也是不同的。任何通过关键字 new 调用的函数都可以当做构造函数。LhzHTML5中文学习网 - HTML5先行者学习网
在构造函数体内,this 指向新创建的对象。如果构造函数体内没有显示的 return 表达式,那么我们就默认返回 this,也就是新建的对象。LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网
function Foo() {LhzHTML5中文学习网 - HTML5先行者学习网
this.bla = 1;LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
Foo.prototype.test = function() {LhzHTML5中文学习网 - HTML5先行者学习网
console.log(this.bla);LhzHTML5中文学习网 - HTML5先行者学习网
};LhzHTML5中文学习网 - HTML5先行者学习网
var test = new Foo();LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网上面的代码将 Foo 作为构造函数进行调用,并将新建对象的原型(__proto__)指向了 Foo.prototype。LhzHTML5中文学习网 - HTML5先行者学习网
如果我们在构造函数内定义返回的 return 表达式,构造函数就会返回整个表达式,但这个返回表达式必须为一个对象。LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网
function Bar() {LhzHTML5中文学习网 - HTML5先行者学习网
return 2;LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
new Bar(); // a new objectLhzHTML5中文学习网 - HTML5先行者学习网
function Test() {LhzHTML5中文学习网 - HTML5先行者学习网
this.value = 2;LhzHTML5中文学习网 - HTML5先行者学习网
return {LhzHTML5中文学习网 - HTML5先行者学习网
foo: 1LhzHTML5中文学习网 - HTML5先行者学习网
};LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
new Test(); // the returned objectLhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网如果 new 被省略,那么函数将不能返回一个新的对象。LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网
function Foo() {LhzHTML5中文学习网 - HTML5先行者学习网
this.bla = 1; // gets set on the global objectLhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
Foo(); // undefinedLhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网上面的例子可能在某些场景下也可以运行,但由于 Javascript 中 this 的工作机制,这里 this 将指向全局对象。LhzHTML5中文学习网 - HTML5先行者学习网
工厂模式LhzHTML5中文学习网 - HTML5先行者学习网
为了能够不使用关键字 new,构造函数将不得不显示返回一个值。LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网
function Bar() {LhzHTML5中文学习网 - HTML5先行者学习网
var value = 1;LhzHTML5中文学习网 - HTML5先行者学习网
return {LhzHTML5中文学习网 - HTML5先行者学习网
method: function() {LhzHTML5中文学习网 - HTML5先行者学习网
return value;LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
Bar.prototype = {LhzHTML5中文学习网 - HTML5先行者学习网
foo: function() {}LhzHTML5中文学习网 - HTML5先行者学习网
};LhzHTML5中文学习网 - HTML5先行者学习网
new Bar();LhzHTML5中文学习网 - HTML5先行者学习网
Bar();LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网上例中使不使用 new 来调用函数 Bar 达到的效果是一样的,将会返回一个新建的包含 method 方法的对象,这里实际上就是一个闭包。LhzHTML5中文学习网 - HTML5先行者学习网
这里需要注意一点,new Bar() 将不会返回 Bar.prototype,而是在 return 表达式内函数 method 的原型对象。LhzHTML5中文学习网 - HTML5先行者学习网
上例中,使用 new 与否在功能上是无差异的。LhzHTML5中文学习网 - HTML5先行者学习网
通过工厂模式创建新的对象LhzHTML5中文学习网 - HTML5先行者学习网
我们经常被提醒不要使用 new,因为一旦忘记了它的使用将导致错误。LhzHTML5中文学习网 - HTML5先行者学习网
为了创建一个对象,我们更愿意使用工厂模式并在工厂模式内构造一个新的对象。LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网function Foo() {
LhzHTML5中文学习网 - HTML5先行者学习网 var obj = {};
LhzHTML5中文学习网 - HTML5先行者学习网 obj.value = 'blub';
LhzHTML5中文学习网 - HTML5先行者学习网 var private = 2;LhzHTML5中文学习网 - HTML5先行者学习网
obj.someMethod = function(value) {LhzHTML5中文学习网 - HTML5先行者学习网
this.value = value;LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
obj.getPrivate = function() {LhzHTML5中文学习网 - HTML5先行者学习网
return private;LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
return obj;LhzHTML5中文学习网 - HTML5先行者学习网
}LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网尽管上例代码比使用 new 时更不容易出错,而且在使用私有变量时将更加方便,但同时也有一些不好的地方:LhzHTML5中文学习网 - HTML5先行者学习网
因为不能共享原型对象,所以需要更多的内存。LhzHTML5中文学习网 - HTML5先行者学习网
为了实现继承,工厂模式需要拷贝另一个对象的所有方法或者将其作为新对象的原型。LhzHTML5中文学习网 - HTML5先行者学习网
放弃原型链只是为了避免使用 new,这似乎与 Javascript 语言的精神相悖。LhzHTML5中文学习网 - HTML5先行者学习网
LhzHTML5中文学习网 - HTML5先行者学习网
总结LhzHTML5中文学习网 - HTML5先行者学习网
尽管使用 new 可能比较容易产生错误,但这并不能成为放弃使用原型链的原因。至于最后采取哪种方式,这需要根据应用的需求而定。最好的方式就是选择一种风格并坚持下去。LhzHTML5中文学习网 - HTML5先行者学习网
简单的说构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象。LhzHTML5中文学习网 - HTML5先行者学习网