最近看《JavaScript高级程序设计(第三版)》第六章面向对象的程序设计时,对其中的一段话,始终理解不了,在仔细读了几遍以及代码实验之后终于彻底搞清楚了,问题如下:
用一个包含所有属性和方法的对象字面量来重写整个原型对象,如下面的例子所示:
function Person(){}; Person.prototype={ name:"Nicholas", age:29, job:"Software Engineer", sayName:function(){ alert(this.name); } };
在上面的代码中,我们将Person.prototype设置为等于一个以对象字面量形式创建的新对象。最终结果相同,但有一个例外:constructor属性不再指向Person了。前面曾经介绍过,每创建一个函数,就会同时创建他的prototype对象,这个对象也会自动获得constructor属性。而我们在这里使用的语法,本质上完全重写了默认的prototype对象,因此constructor属性也就变成了新对象的constructor属性(指向Object函数),不再指向Person函数。
以上是书中原话,一直想不明白到底是如何转变的。现把我想通的思路整理如下:
首先将重写Person.propotype的字面量形式改写如下:
其次,理解两句话<span style="background-color: rgb(255, 204, 102);">Person.prototype = new Object();</span> Person.prototype.name = "Nicholas"; Person.prototype.age=29; Person.prototype.job="Software Engineer"; Person.prototype.sayName = function(){alert(this.name);};
1.prototype就是通过调用构造函数而创建的那个对象实例的原型对象。
2.每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始。如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性。如果在原型对象中找到了这个属性,则返回该属性的值。
可能大家到这已经明白怎么回事了,但为了更清楚,我们使用图和代码再次解释和验证一下。
var friend = new Person();
alert(friend.constructor==Object);//true
这里会输出Object的过程是先查找friend内有无prototype属性,若无查找friend的原型对象即Person.prototype,Person.prototype内无constructor属性,则继续寻找Person.prototype的原型对象即Object.prototype的constructor属性,为Object{}。
因此书中提供了一种指定构造函数的方式,即在Person.prototype内定义属性constructor为Person。这样就不会再去Person.prototype的原型对象内去寻找constructor了,因为重新定义了constructor属性,因此也导致了它的[[Enumerable]]属性为true。<!DOCTYPE html> <html> <head> <meta charset='UTF-8'/> <script type="text/javascript"> function Person(){ } Person.prototype = { name:"dx" }; function Human(){ }; var person = new Person(); var human = new Human(); window.onload=function(){ alert("person.constructor==Person:"+(person.constructor==Person));//false alert("person.constructor==Object:"+(person.constructor==Object));//true alert("human.constructor==Human:"+(human.constructor==Human));//true alert("human.constructor==Object:"+(human.constructor==Object));//false alert("Person.prototype的constructor是否来自本身:"+Person.prototype.hasOwnProperty("constructor"));//false alert("Human.prototype的constructor是否来自本身:"+Human.prototype.hasOwnProperty("constructor")); //true } </script> </head> <body> </body> </html>
如有错误,敬请大家积极批评指证,谢谢。
重写prototype,构造器更改的原理剖析
最新推荐文章于 2024-02-09 07:45:00 发布