`
sitengfei
  • 浏览: 3504 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

js原型链图解

阅读更多

http://www.jb51.net/article/30750.htm

      此文源于这篇文章,读了之后感觉原文有点乱,所以整理了一下,画了一张图,初学js不知道对原型链的理解对不对,还请各位大神指教。

     下面图中被一条红线连起来的那3个对象,就是一条原型链。我的理解是:原型链就是由_proto_指针连起来的几个对象组成的一条对象链,使链下游的对象能继承链上游对象(**.prototype)的方法和属性。


直接看代码吧

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
//原型链 用于实现js的继承特性
Object.prototype.oShowMe = function (){document.write("function of the root obj<br>");};
Function.prototype.fShowMe = function(){document.write("function of the Function obj<br>");};

function MyFunc(){
	var name = 'tom';
}
MyFunc.prototype.mShowMe = function(){document.write("user-defined function<br>");};
var mfObj = new MyFunc();
mfObj.mShowMe();//output: user-defined function
mfObj.oShowMe();//output: function of the root obj
//mfObj.fShowMe();//output:对象不支持“fShowMe”属性或方法 
MyFunc.fShowMe();//output: function of the Function obj
MyFunc.oShowMe();//output: function of the root obj	
//对new出来的对象的继承是无效的
//var OmfObj = new mfObj;
//OmfObj.oShowMe();//output: 对象不支持此操作 
</script>
</head>
<body>

</body>
</html>
 

这段代码可以直接复制到一个jsp文件运行,读者可以先看下运行结果,自己对照图片思考下。这里我想用自己不科学的语言给你点提示:

1. 每个对象都有两个隐含属性:prototype和_proto_,以实现继承。

2. prototype也是个指针,指向自身的prototype即<this.prototype>,用于被子类继承。

3. _proto_可以理解为一个指针,指向父类的 <父类.prototype>,用于继承父类在prototype中声明的属性。

ps:上述几条为了方便理解,说的很不全面。也不标准,也为js里没有父类这种说法。

 

 

在上面这段代码中,我给Object,Function这两个js内部对象增加了oShowMe(),fShowMe()这两个方法,以查看Object和Function的子类有没有继承到这两个对象(的prototype)。

从其运行结果可以知道:

1. Object对象是所有对象的根类 ,所有的对象都继承自Object,所以图中几个<**.prototype>最后都指向<Object.prototype>,同时所有对象都能使用oShowMe()这个方法。

 

2. function MyFunc是个对象,继承自Object类 ,废话,第一条里面不说了么Object是所有对象的根,root

 

function aFunc(a,b){
return a+b;
}

 这是最常见的一种声明js函数的方法,同时这个函数又是一个js对象,最初我对这种方法非常不理解,干嘛要搞的这么含糊,想java那样定义明确的class,对象必须要new的多好,但这种规则,正是js比java灵活的体现,如果java是郭靖,那js一定是黄老邪,实在是太邪了。。。

跑题了,下面看另一种声明js函数的方法

 

Function aFunc = new Function(a,b,"return a+b");

 这个函数是以对象的形式声明的,用Function声明对象的效果与用function声明函数是一样的,而且function这种声明方式(其实这样的声明的function被称为<aFunc.prototype>的constructor,即构造器,看图)在js解释器中的处理,也是先转换为Function对象声明的方式的。

所以如第一段代码所示:函数MyFunc可以调用到Object中的函数oShowMe();,因为MyFunc这个函数(也是对象)继承自Object。

3. 原型链的作用是实现继承:

如图中红线所示:我们调用mfObj.mShowMe();时,mfObj对象并未声明方法mShowMe,所以它沿着原型链向上层查找,在<MyFunc.prototype>中找到了mShowMe()。调用mfObj.oShowMe();时,mfObj同样沿着原型链向上层查找到<Object.prototype>才找到oShowMe();

这就实现了js方法中的继承,同时验证了提示中的第二,第三条。

 

 

我翻了下书总结下js实现继承的其他方法

1. 对象冒充

2. call()方法

3. apply()方法

4. 原型链

5.原型链+对象冒充 混合式

这些方法我还没看,看了之后有新的感悟的话,还会回来更新。

 

可能有些地方说的不太清楚,说的清楚的估计也难免有错误,希望大神不吝指正,大家共同学习。

 

 

 

 

 

  • 大小: 106.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics