function Person(){} Person.prototype.name = 'lzl'; Person.prototype.showName = function(){ document.write(this.name); } var p = new Person(); p.showName();
上面这段代码使用了原型而不是构造函数初始化对象。这样做与直接在构造函数内定义属性有什么不同呢?
☞ 构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构造函数内定义的属性。
☞ 构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的两个对象不共享实例。
☞ 构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义的函数来说也是可见的。
下面这段代码可以验证以上问题:
function Foo(){ this.prop1 = 'lzl'; this.func1 = function(){ document.write(this.prop2); } } Foo.prototype.prop2 = 'lzljj'; Foo.prototype.func2 = function(){ document.write(this.prop2); } var foo1 = new Foo(); var foo2 = new Foo(); document.write(foo1.func1 == foo2.func1);// false document.write(foo1.func2 == foo2.func2);// true
两者有各自的适用范围,那么我们什么时候使用原型,什么时候使用构造函数内定义来创建属性呢?
☞ 除非必须用构造函数闭包,否则尽量用原型定义成员函数,因为这样可以减少开销。
☞ 尽量在构造函数内定义一般成员,尤其是对象或数组,因为用原型定义的成员是多个实例共享的。