话题源于:
js一个很奇怪的问题
ecma太拙嘴饶舌,本文力图用简单的测试示例来说明问题
任意创建一个函数,其原型prototype立刻被自动创建:
实例化Coo的原型prototype被置于作用域scope的最顶端:
在实例化Coo之前修改其原型prototype,其作用域scope顶端自动调整为修改后的原型prototype,并且实例c1可沿原型链找到method方法
在实例化过程内部重新设置Coo的 属性prototype:
所以在实例化过程内部,只能基于 原型prototype来扩展或修改方法
盘根究底,既然在实例化过程内部重新设置Coo的 属性prototype,
那么Coo的 原型prototype又会去了哪儿呢?
啰嗦了一大堆,简而言之:
函数的原型prototype是在实例化(或执行函数自身)之前就被自动创建(可以被修改或重置引用)的。
而在实例化(或执行函数自身)过程中, 重置的prototype已沦为一个普普通通的对象属性了,
但是他却并不会干扰正常的javascript实例方法的原型链查找机制。
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实例方法的原型链查找机制。
1 楼
lifesinger 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