http://www.cnblogs.com/cmptlgg/ 我的博客园 重写函数对象的prototype属性值:会切断实例的[[Prototype]]内部属性和最初函数对象的prototype(原型对象)的联系 这个例子引用js高级第三版; /* 这是高三对此实现的解释。 尽管可以随时为原型添加属性和方法,并且修改能够立即在所有对象实例中反映出来,但如果是重 写整个原型对象,那么情况就不一样了。我们知道,调用构造函数时会为实例添加一个指向最初原型的 [[Prototype]]指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。 请记住:实例中的指针仅指向原型,而不指向构造函数。看下面的例子。 */ 下面我们来看看ecma标准中是如何实现这些操作的;个人只是简说,并不完全。 function Person(){//创建函数时,就会创建一个函数对象P在函数对象创建的算法中 会为P对象创建一些属性其中包括内部属性(用[[]]表示)。内部属性初始化为P.[[prototype]]=Function.prototype; P.prototype=new Object()产生一个新对象充当P的原型对象; } var friend = new Person(); //new运算符会调用 之前Person函数对象的[[Construct]] 此内部方法,看看它的算法步奏(简写并不完全);obj 为新创建的 ECMAScript 原生对象。为此Obj对象创建内部属性;obj.[[prototype]]=Person.prototype;获取前的函数对象中的prototype属性。后面一些步奏省略。最后会返回[[construct]]的结果是一个对象。 //我们知道,创建函数对象时prototype属性值是初始化的new Object()。 Person.prototype = {/*此处修改了之前创建的函数对象P.prototype, 但是new出来的新对象的[[Prototype]]的值 在修改p.prototype之前就已经初始化为obj.[[prototype]]=Person.prototype.所以new出的对象的[[Prototype]]的值还是指向之前的Person.prototype。可以看到此值并没有被修改*/ constructor: Person, name : "Nicholas", age : 29, job : "Software Engineer", sayName : function () { alert(this.name); } }; friend.sayName(); //error 所以这里报错了。关于这里是如何查找对象的属性就不说了。不在这章的范围。 //这里我们把var friend = new Person();放到修改prototype属性的后面情况又不一样了。原因还是因为有没有把new出的对象的[[Prototype]]属性给修改。如果给修改了。就指向修改的值。 function Person(){ } Person.prototype = {这里直接把函数对象的prototype属性值给修改成一个新对象; constructor: Person, name : "Nicholas", age : 29, job : "Software Engineer", sayName : function () { alert(this.name); } }; var friend = new Person();//这里最后会返回[[Construct]]的结果是一个对象。在此内部方法的行为中很明显它的NEW出的新对象的[[Prototype]]=Person.prototype;之前创建的函数对象的prototype的值被修改了。这里的值是一个指针,指向一个对象,称为原型对象。 friend.sayName(); 弹出"Nicholas";//最后总结一下,归根到底就是一个执行流程的一个先后顺序的关系,顺序不一样。结果也会不同。此文章当中有什么错误的地方,请大家评论下,谢谢 web技术+winapp技术 学习交流群162791594
时间: 2024-11-01 14:36:28