原文地址:http://www.excelib.com/article/245/show
constructor的属性
在function的prototype属性对象中默认有一个叫constructor的属性,这个属性默认会指向function方法自身,比如前一节例子中Person的prototype属性对象的constructor属性就指向了Person,但是Teacher的prototype由于被我们赋予了新的值,所以他的constructor属性就不存在了(使用Person创建出来的person对象自身并没有constructor属性),这时如果调用teacher.constructor就会返回Person函数(因为最后会沿着prototype找到person的prototype属性对象的constructor属性),为了可以使用constructor属性得到正确的构造函数,我们可以手动给Teacher的prototype属性对象的constructor属性赋值为Teacher,代码如下
1 2 3 4 5 | Teacher.prototype = new Person(); Teacher.prototype.logPrototype = function () { console.log( "prototype" ); } Teacher.prototype.constructor = Teacher; |
使用prototype属性注意事项
在使用prototype时要特别注意以下三点:
1、prototype属于function类型对象中的属性,prototype自身的属性可以被function创建出来的object类型实例对象使用,但是object类型的实例对象自身并没有prototype属性;
2、如果要给function对象的prototype属性赋予新的值而且又要添加新的属性,则需要先赋予新值然后再添加新的属性,否则在赋值时会将原先添加的属性覆盖掉,我们看下面的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 | function log(msg){ console.log(msg); } function Person(){} function Teacher(){} Teacher.prototype.logPrototype = function () { log( "prototype" ); } Teacher.prototype = new Person(); var teacher = new Teacher(); teacher.logPrototype(); |
这里在执行最后一句代码teacher.logPrototype()的时候会报错,这是因为给Teacher的prototype属性对象添加了logPrototype属性方法后又给prototype赋值为了new Person(),新的prototype中并没有logPrototype属性方法,所以调用就会出错,也就是说logPrototype被新的对象覆盖了;
3、function创建的对象在调用属性时是实时按prototype链依次查找的,而不是将prototype中的属性关联到创建出来的对象本身,所以创建完object实例对象后再修改function的prototype也会影响到创建出来对象的调用,我们看下面的例子
1 2 3 4 5 6 | function Teacher(){} var teacher = new Teacher(); Teacher.prototype.log = function (msg) { console.log(msg); } teacher.log( "hello" ); //hello |
这里的log方法是在teacher对象已经创建完成后添加的,但是在teacher对象中仍然可以使用,也就是说prototype中的属性是动态查询的。
另外,使用prototype除了可以实现继承之外还可以节约内存,因为无论使用function创建多少对象,他们所指向的prototype对象在内存中只有一份,当然有利就有弊,没有绝对的完美,使用prototype中的属性会比直接使用对象中定义的属性在执行效率上理论来说会低一些。