原型模式
1.prototype
前面在提到Function类型的属性提到了length和prototype,prototype属性是一个非常重要的属性。这个属性是一个指针,指向一个对象。该对象的用途是包含可以由特定类型的所有实例共享的属性和方法,即指向函数的原型对象。这个原型对象中有个一个constructor属性,指向prototype属性所在函数的指针。做如下测试:
function Person(){} Person.prototype.name = "nick"; alert(Person.prototype.constructor);
结果输出的是Person的构造函数。也就是说Person.prototype指向了Person的原型对象,Person.prototype.constructor又指回了Person。
创建一个实例:Person person = new Person();person有一个内部属性_proto_指向Person.prototype,这样建立了实例与原型对象之间的连接,而与构造函数无关。
每当读取某个对象的某个属性时,都会执行一次搜索。首先查找实例本身是否存在该属性,如果没有则查找原型对象中是否存在这样的属性。因此当对象实例中添加一个和原型对象中同名的方法或属性,会屏蔽掉原型对象中同名的属性(因为已经在实例中查找到了该属性,不会继续搜索原型对象),但不会修改原型对象中的属性值,当然如果delete掉实例中的同名属性,又可以访问原型对象中的该属性了。
重写原型对象会切断现有原型与任何之前已经存在的对象实例之间的联系,因此实例引用的是最初的模型。
原型模式的缺点:如果所有的实例共享的属性中有引用类型值,则很不安全。
2.构造函数模式和原型模式
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; } Person.prototype = { constructor : Person, sayName : function(){ alert(this.name); } }
这样所有实例属性constructor和sayName方法,但是又有自己的name,age,job属性。
PS:像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中,用户也可以自定义构造函数,如同上面的例子,注意构造函数名首字母大写,以便区别普通函数。
浙公网安备 33010602011771号