Javascript学习笔记7 原型链的原理


Posted in Javascript onJanuary 11, 2010

我们先看看这样一段代码:

<script type="text/javascript"> 
var Person = function () { }; 
var p = new Person(); 
</script>

很简单的一段代码,我们来看看这个new究竟做了什么?我们可以把new的过程拆分成以下三步:

<1> var p={}; 也就是说,初始化一个对象p。

<2> p.__proto__=Person.prototype;

<3> Person.call(p);也就是说构造p,也可以称之为初始化p。

关键在于第二步,我们来证明一下:

<script type="text/javascript"> 
var Person = function () { }; 
var p = new Person(); 
alert(p.__proto__ === Person.prototype); 
</script>

这段代码会返回true。说明我们步骤2的正确。

那么__proto__是什么?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。

好,概念说清了,让我们看一下下面这些代码:

<script type="text/javascript"> 
var Person = function () { }; 
Person.prototype.Say = function () { 
alert("Person say"); 
} 
var p = new Person(); 
p.Say(); 
</script>

这段代码很简单,相信每个人都这样写过,那就让我们看下为什么p可以访问Person的Say。

首先var p=new Person();可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性,于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了Person.prototype.Say=function(){}; 于是,就找到了这个方法。

好,接下来,让我们看个更复杂的。

<script type="text/javascript"> 
var Person = function () { }; 
Person.prototype.Say = function () { 
alert("Person say"); 
} 
Person.prototype.Salary = 50000; 
var Programmer = function () { }; 
Programmer.prototype = new Person(); 
Programmer.prototype.WriteCode = function () { 
alert("programmer writes code"); 
}; 
Programmer.prototype.Salary = 500; 
var p = new Programmer(); 
p.Say(); 
p.WriteCode(); 
alert(p.Salary); 
</script>

我们来做这样的推导:

var p=new Programmer()可以得出p.__proto__=Programmer.prototype;

而在上面我们指定了Programmer.prototype=new Person();我们来这样拆分,var p1=new Person();Programmer.prototype=p1;那么:

p1.__proto__=Person.prototype;

Programmer.prototype.__proto__=Person.prototype;

由根据上面得到p.__proto__=Programmer.prototype。可以得到p.__proto__.__proto__=Person.prototype。

好,算清楚了之后我们来看上面的结果,p.Say()。由于p没有Say这个属性,于是去p.__proto__,也就是Programmer.prototype,也就是p1中去找,由于p1中也没有Say,那就去p.__proto__.__proto__,也就是Person.prototype中去找,于是就找到了alert(“Person say”)的方法。

其余的也都是同样的道理。

这也就是原型链的实现原理。

最后,其实prototype只是一个假象,他在实现原型链中只是起到了一个辅助作用,换句话说,他只是在new的时候有着一定的价值,而原型链的本质,其实在于__proto__!

Javascript 相关文章推荐
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
Mar 28 Javascript
js indexOf()定义和用法
Oct 21 Javascript
解决ueditor jquery javascript 取值问题
Dec 30 Javascript
jQuery中parents()方法用法实例
Jan 07 Javascript
jQuery插件简单实现方法
Jul 18 Javascript
jquery中的工具使用方法$.isFunction, $.isArray(), $.isWindow()
Aug 09 Javascript
JS实现方向键切换输入框焦点的方法
Aug 19 Javascript
zTree实现节点修改的实时刷新功能
Mar 20 Javascript
gulp安装以及打包合并的方法教程
Nov 19 Javascript
分享vue里swiper的一些坑
Aug 30 Javascript
Node.js操作MongoDB数据库实例分析
Jan 19 Javascript
vue css 引入asstes中的图片无法显示的四种解决方法
Mar 16 Javascript
Javascript学习笔记6 prototype的提出
Jan 11 #Javascript
Javascript学习笔记5 类和对象
Jan 11 #Javascript
Javascript学习笔记4 Eval函数
Jan 11 #Javascript
Javascript学习笔记2 函数
Jan 11 #Javascript
Javascript学习笔记1 数据类型
Jan 11 #Javascript
IE bug table元素的innerHTML
Jan 11 #Javascript
javascript instanceof 与typeof使用说明
Jan 11 #Javascript
You might like
PHP开发文件系统实例讲解
2006/10/09 PHP
php 数组的指针操作实现代码
2011/02/08 PHP
浅谈PHP面向对象之访问者模式+组合模式
2017/05/22 PHP
PHP session垃圾回收机制实例分析
2019/06/28 PHP
抽出www.templatemonster.com的鼠标悬停加载大图模板的代码
2007/07/11 Javascript
JS 跳转页面延迟2种方法
2013/03/29 Javascript
jQuery后代选择器用法实例
2014/12/23 Javascript
javascript委托(Delegate)blur和focus用法实例分析
2015/05/26 Javascript
JavaScript String 对象常用方法详解
2016/05/13 Javascript
NodeJS连接MongoDB数据库时报错的快速解决方法
2016/05/13 NodeJs
jQuery实现的导航下拉菜单效果示例
2016/09/05 Javascript
angularjs实现多张图片上传并预览功能
2017/02/24 Javascript
在百度搜索结果中去除掉一些网站的资料(通过js控制不让显示)
2017/05/02 Javascript
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
knockoutjs模板实现树形结构列表
2017/07/31 Javascript
vue父组件向子组件传递多个数据的实例
2018/03/01 Javascript
Vue项目引进ElementUI组件的方法
2018/11/11 Javascript
JavaScript canvas绘制渐变颜色的矩形
2020/02/18 Javascript
[01:02]2014 DOTA2国际邀请赛中国区预选赛 现场抢先看
2014/05/22 DOTA
[03:26]《DAC最前线》之EG经理自述DOTA2经历
2015/02/02 DOTA
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
在Python中使用swapCase()方法转换大小写的教程
2015/05/20 Python
基于python实现微信模板消息
2015/12/21 Python
python爬取淘宝商品详情页数据
2018/02/23 Python
Python Series从0开始索引的方法
2018/11/06 Python
python实现的爬取电影下载链接功能示例
2019/08/26 Python
python检查目录文件权限并修改目录文件权限的操作
2020/03/11 Python
canvas与html5实现视频截图功能示例
2016/12/15 HTML / CSS
英国婴儿和儿童服装网站:Vertbaudet
2018/04/02 全球购物
巴西葡萄酒商店:Divvino
2020/02/22 全球购物
领导调研接待方案
2014/02/27 职场文书
旅游市场营销方案
2014/03/09 职场文书
文秘专业应届生求职信
2014/05/26 职场文书
公司法人授权委托书范本
2014/09/12 职场文书
2014年绩效考核工作总结
2014/12/11 职场文书
埃及王子观后感
2015/06/16 职场文书