浏览 2854 次
锁定老帖子 主题:谈谈javascript原型构造机制
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-20
最后修改:2009-10-01
js一个很奇怪的问题
话题源于:ecma太拙嘴饶舌,本文力图用简单的测试示例来说明问题 任意创建一个函数,其原型prototype立刻被自动创建: function Coo(){}; alert(Coo.prototype.constructor); //=>function Coo(){} 实例化Coo的原型prototype被置于作用域scope的最顶端: function Coo(){ alert(Coo.prototype.constructor); } var c1 = new Coo(); // => function Coo(){ ..} 在实例化Coo之前修改其原型prototype,其作用域scope顶端自动调整为修改后的原型prototype,并且实例c1可沿原型链找到method方法 function Coo(){ alert(Coo.prototype.method); // => function(){} 作用域scope顶端自动调整为修改后的原型prototyp } Coo.prototype = { method : function(){} } var c1 = new Coo(); // => function(){} alert(c1.method); // => function(){} 在实例化过程内部重新设置Coo的属性prototype: function Coo(){ alert(Coo.prototype.method); // => undefined 作用域scope顶端依旧为默认自动创建的原型prototype Coo.prototype = { method : function(){} } //注意:上面这行重新设置了Coo的[b]属性[/b]prototype, //它已不再是Coo自动创建或是自动调整后的原型prototype了——这正是javascript原型机制的核心 } var c1 = new Coo(); // => function(){} //所以,虽然貌似: alert(c1.prototype.method) // => function(){} //但此[b]属性[/b]——"prototype"(),已非彼[b]原型[/b]——"prototype"了: alert(c1.method); // => undefined 所以在实例化过程内部,只能基于原型prototype来扩展或修改方法 function Coo(){ alert(Coo.prototype.method); // => undefined Coo.prototype.method = function(){}; // 在正宗原型prototype上扩展,非山寨! } var c1 = new Coo(); // => function(){} alert(c1.prototype.method); // => function(){} alert(c1.method); // => function(){}; 盘根究底,既然在实例化过程内部重新设置Coo的属性prototype, 那么Coo的原型prototype又会去了哪儿呢? function Coo(){ Coo.prototype = { method : function(){ alert("实例化中");} }; }; Coo.prototype = { constructor : Coo, method : function(){} } var c1 = new Coo(); alert(c1.prototype.method); // => function(){ alert("实例化中");} 糟糕! alert(c1.method); // => function(){} 谢天谢地! alert(c1.constructor === Coo ); // => true; 原型链都还在,但它们似乎只是在内部被保存起来了 啰嗦了一大堆,简而言之: 函数的原型prototype是在实例化(或执行函数自身)之前就被自动创建(可以被修改或重置引用)的。 而在实例化(或执行函数自身)过程中,重置的prototype已沦为一个普普通通的对象属性了, 但是他却并不会干扰正常的javascript实例方法的原型链查找机制。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-08-20
最后修改:2009-08-20
zbm2001 写道 实例化Coo的原型prototype被置于作用域scope的最顶端: function Coo(){ alert(Coo.prototype.constructor); } var c1 = new Coo(); // => function Coo(){ ..} 这个说法不严谨,Coo.prototype 是在 parse 阶段就已添加,而不是 runtime 时才添加。 比如: function Coo(){ } debugger 在 firebug 下,debugger 处已经可以看到 Coo.prototype 为 Object |
|
返回顶楼 | |
发表时间:2009-08-20
zbm2001 写道
话题源于:js一个很奇怪的问题
啰嗦了一大堆,简而言之: 函数的原型prototype是在实例化(或执行函数自身)之前就被自动创建(可以被修改或重置引用)的。 而在实例化(或执行函数自身)过程中,重置的prototype已沦为一个普普通通的对象属性了, 但是他却并不会干扰正常的javascript实例方法的原型链查找机制。 楼主总结的还是比较简明易懂,例子也挺不错,再一次证明了javaeye很多牛人,这个问题也总算告一阶段了 |
|
返回顶楼 | |
发表时间:2009-08-20
最后修改:2009-08-20
zbm2001 写道
盘根究底,既然在实例化过程内部重新设置Coo的属性prototype,
那么Coo的原型prototype又会去了哪儿呢? Js代码 function Coo(){ Coo.prototype = { method : function(){ alert("实例化中");} }; }; Coo.prototype = { constructor : Coo, method : function(){} } var c1 = new Coo(); alert(c1.prototype.method); // => function(){ alert("实例化中");} 糟糕! alert(c1.method); // => function(){} 谢天谢地! alert(c1.constructor === Coo ); // => true; 原型链都还在,但它们似乎只是在内部被保存起来了 啰嗦了一大堆,简而言之: 函数的原型prototype是在实例化(或执行函数自身)之前就被自动创建(可以被修改或重置引用)的。 而在实例化(或执行函数自身)过程中,重置的prototype已沦为一个普普通通的对象属性了, 但是他却并不会干扰正常的javascript实例方法的原型链查找机制。 alert(c1.prototype.method); // => function(){ alert("实例化中");} 糟糕! 的注释貌似不对哈
|
|
返回顶楼 | |
发表时间:2010-03-01
最后修改:2010-03-01
var CooGlobal; function Coo(){ Coo.prototype = { method : function(){ alert("实例化中");} }; CooGlobal = Coo; }; var c1 = new Coo(); console.log(c1.__proto__.method); //undefined var gcoo = new CooGlobal(); console.log(gcoo.__proto__.method); //function() var c2 = new Coo(); console.log(c2.__proto__.method);//function() 我认为应该是在对象实例化的时候改变了Coo类的定义,把Coo指向了一个新类,并不是什么沦为一个普普通通的对象属性
|
|
返回顶楼 | |