JavaScript原型链prototype chain

dh20156 2008-07-14 10:14:28
为了在JavaScript更好地去面向对象,我们需要看清楚一些事情的本质,比如:原型链!

<script type="text/javascript">

/*
每个对象实例都有个属性成员用于指向到它的instanceof 对象(暂称为父对象)的原型(prototype)
我们把这种层层指向父原型的关系称为[原型链 prototype chian]
原型也具有父原型,因为它往往也是一个对象实例,除非我们人为地去改变它


Function的父原型指向到Function的原型,Function.prototype的父原型是Object的原型
Object的父原型也指向到Function的原型,Object.prototype是所有父原型的顶层
在spiderMonkey引擎中,父原型可以通过 __proto__ 进行访问
*/

Function.prototype.hi = function(){alert('hi Function');}
Object.prototype.hi = function(){alert('hi Object');}

var a = function(){
this.txt = "a";
}
a.prototype = {
say:function(){alert('a');}
}

alert(a instanceof Function);//a是Function的实例;
alert(a.__proto__ === Function.prototype);//a的父原型指向到Function的原型;

alert(Function instanceof Object);//Function是Object的实例;
alert(Function.__proto__ === Function.prototype);//Function的父原型指向到Function的原型;
alert(Function.prototype.__proto__ === Object.prototype);//Function的原型的父原型指向到Object的原型

alert(Object.__proto__ === Function.prototype);//Object的父原型指向到Function的原型;
alert(Object.prototype.__proto__);//Object的原型是所有父原型的顶端,它不再具有父原型;


alert(a.prototype instanceof Object);//a的原型也是一个对象
alert(a.prototype.__proto__ === Object.prototype);//a的原型的父原型指向Object的原型



var A = function(){};
A.prototype = new a();
A.prototype.say = function(){
alert('A');
}

alert(A instanceof Function);//A是Function的实例
alert(A.__proto__ === Function.prototype);//A的父原型指向到Function的原型
alert(A.prototype instanceof a);//A的原型是a的实例
alert(A.prototype.__proto__ === a.prototype);//A的原型的父原型指向到a的原型


var iA = new A();//iA是A的实例,iA.__proto__ === A.prototype
var iB = new a();//iB是a的实例,iB.__proto__ === a.prototype

iA.hi();
/*
iA本身没有hi方法(构造中没有,自己也没有定义过),
于是找iA的prototype,没有找到,
于是找iA.__proto__即A.prototype,也没有找到,
于是再找A.prototype.__proto__即a.prototype,仍然没有发现,
继续查找a.prototype.__proto__即Object.prototype,哇,发现了hi,于是调用它,停止查找
输出:hi Object
*/

iB.hi();
/*
iB本身没有hi方法(构造中没有,自己也没有定义过),
于是找iB的prototype,没有找到,
于是找iB.__proto__即a.prototype,仍然没有发现,
继续查找a.prototype.__proto__即Object.prototype,哇,发现了hi,于是调用它,停止查找
输出:hi Object
*/

a.hi();
/*
a本身没有hi方法(构造中没有,自己也没有定义过),
于是找a的prototype,没有找到,
于是找a.__prototype__既Function.prototype,哇,发现了hi,于是调用它,停止查找
输出:hi Function
*/

iA.say();
/*
iA本身没有say方法(构造中没有,自己也没有定义过),
于是找iA的prototype,没有找到,
于是找iA.__proto__即A.prototype,也没有找到,
于是再找A.prototype.__proto__即a.prototype,哇,发现了hi,于是调用它,停止查找
所以,这里调用的是A.prototype.say
输出:A
*/

iB.say();
/*
iB本身没有say方法(构造中没有,自己也没有定义过),
于是找iB的prototype,没有找到,
于是找iB.__proto__即a.prototype,哇,发现了say,于是调用它,停止查找
所以,这里调用的是a.prototype.say
输出:a
*/

iA.bad();
/*
iA本身没有hi方法(构造中没有,自己也没有定义过),
于是找iA的prototype,没有找到,
于是找iA.__proto__即A.prototype,也没有找到,
于是再找A.prototype.__proto__即a.prototype,仍然没有发现,
继续查找a.prototype.__proto__即Object.prototype,终于是找不到了,停止查找
返回错误,iA.bad不是一个function
*/

</script>

原文及其他相关部分请参见:
http://www.v-ec.com/dh20156/article.asp?id=157
http://www.v-ec.com/dh20156/article.asp?id=158
http://www.v-ec.com/dh20156/article.asp?id=159

如文中有不妥之处,欢迎大家讨论! ^_^
...全文
1543 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
gengzhw 2009-03-04
  • 打赏
  • 举报
回复
记录
rczjp 2008-09-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 s_liangchao1s 的回复:]
收藏 Mark
[/Quote]
dh20156 2008-07-29
  • 打赏
  • 举报
回复
Meteoric_cry同学,__proto__是SpiderMonkey的JavaScript引擎里的私有属性(JScript中木有),用于指向到实例的instanceof对象的prototype。

至于你说的其他的测试结果,在理解本文后应该会看得很清楚的。

另,因为本文中存在许多笔误,请转到:

http://www.v-ec.com/dh20156/article.asp?id=157

查看,欢迎讨论! ^_^
Meteoric_cry 2008-07-28
  • 打赏
  • 举报
回复
而且我实了后发现
<script type="text/javascript">

//Function.prototype.hi = function(){alert('hi Function');}
Object.prototype.hi = function(){alert('hi Object');}

var a = function(){
this.txt = "a";
}
a.prototype = {
say:function(){alert('a');}
}
var A = function(){};
A.prototype = new a();
A.prototype.say = function(){
alert('A');
}
var iA = new A();//iA是A的实例,iA.__proto__ === A.prototype
var iB = new a();//iB是a的实例,iB.__proto__ === a.prototype
//alert(typeof a._prototype_)
iA.hi();
iB.hi();
a.hi()
A.hi()
</script>
得到的全是 hi Object
哈哈````
只能说明对象的关系搞的不是很清楚
Meteoric_cry 2008-07-28
  • 打赏
  • 举报
回复

iA.hi();
/*
iA本身没有hi方法(构造中没有,自己也没有定义过),
于是找iA的prototype,没有找到,
于是找iA.__proto__即A.prototype,也没有找到,
于是再找A.prototype.__proto__即a.prototype,仍然没有发现,
继续查找a.prototype.__proto__即Object.prototype,哇,发现了hi,于是调用它,停止查找
输出:hi Object
*/

a.hi();
/*
a本身没有hi方法(构造中没有,自己也没有定义过),
于是找a的prototype,没有找到,
于是找a.__prototype__既Function.prototype,哇,发现了hi,于是调用它,停止查找
输出:hi Function
*/
我就想问一个问题
a.__prototype_到底是什么,!??我用IE6.0是没定义undefined,你前后说的有矛盾
而且A.hi()也是输出的是 hi Funciton
这个你没解释好
new A() 或是new a()
他得到的其实就是一对象,如果他的原型里没有这个方法,他就直接找上一层的prototype也就是Object的hi()方法.如果有就直接调用当前的 而A 与a是一个函数对象.如果他们没有hi()方法,输出的也会是hi object
dead_of_winter 2008-07-14
  • 打赏
  • 举报
回复
总而言之 接分
tengfei3003 2008-07-14
  • 打赏
  • 举报
回复
藏一下
s_liangchao1s 2008-07-14
  • 打赏
  • 举报
回复
哈哈 楼主自己给自己叫上了。。。。
dh20156 2008-07-14
  • 打赏
  • 举报
回复
只能怀疑自己治学不严谨! - -!

再次更正:

iA.bad()的注释部分

iA本身没有hi方法

应为

iA本身没有bad方法
suiqirui19872005 2008-07-14
  • 打赏
  • 举报
回复
jf
dh20156 2008-07-14
  • 打赏
  • 举报
回复
再次更正,郁闷~~··

iA.say();
/*
iA本身没有say方法(构造中没有,自己也没有定义过),
于是找iA的prototype,没有找到,
于是找iA.__proto__即A.prototype,也没有找到,
于是再找A.prototype.__proto__即a.prototype,哇,发现了hi,于是调用它,停止查找
所以,这里调用的是A.prototype.say
输出:A
*/

应该为:


iA.say();
/*
iA本身没有say方法(构造中没有,自己也没有定义过),
于是找iA的prototype,没有找到,
于是找iA.__proto__即A.prototype,哇,发现了say,于是调用它,停止查找
所以,这里调用的是A.prototype.say
输出:A
*/
cgisir 2008-07-14
  • 打赏
  • 举报
回复
接分...
muxrwc 2008-07-14
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 s_liangchao1s 的回复:]
引用 2 楼 muxrwc 的回复:
接分。。。


哈哈 没用拉 沙发是我的。。。
[/Quote]

T_T
dh20156 2008-07-14
  • 打赏
  • 举报
回复
更正一个地方,手误:

“于是找a.__prototype__既Function.prototype”

应该为:

于是找a.__proto__既Function.prototype
nicholsky 2008-07-14
  • 打赏
  • 举报
回复
需要用到的时候再深入研究,接分。
dh20156 2008-07-14
  • 打赏
  • 举报
回复
自己占一楼先
s_liangchao1s 2008-07-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 muxrwc 的回复:]
接分。。。
[/Quote]

哈哈 没用拉 沙发是我的。。。
s_liangchao1s 2008-07-14
  • 打赏
  • 举报
回复
收藏 Mark
muxrwc 2008-07-14
  • 打赏
  • 举报
回复
在接。。
muxrwc 2008-07-14
  • 打赏
  • 举报
回复
接分。。。
加载更多回复(6)

87,923

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧