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 相关文章推荐
javascript 闭包疑问
Dec 30 Javascript
javascript 构造函数强制调用经验总结
Dec 02 Javascript
js自动下载文件到本地的实现代码
Apr 28 Javascript
JS获取当前网址、主机地址项目根路径
Nov 19 Javascript
javascript中数组的concat()方法使用介绍
Dec 18 Javascript
jQuery ajax中使用confirm,确认是否删除的简单实例
Jun 17 Javascript
深入理解JS中的Function.prototype.bind()方法
Oct 11 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
May 11 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
Dec 23 Javascript
vue + webpack如何绕过QQ音乐接口对host的验证详解
Jul 01 Javascript
vue拖拽排序插件vuedraggable使用方法详解
Aug 21 Javascript
Vue程序化的事件监听器(实例方案详解)
Jan 07 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中Session的概念
2006/10/09 PHP
php中删除字符串中最先出现某个字符的实现代码
2013/02/03 PHP
php Hex RGB颜色值互换的使用
2013/05/10 PHP
探讨GDFONTPATH能否被winxp下的php支持
2013/06/21 PHP
php利用单例模式实现日志处理类库
2014/02/10 PHP
Linux下创建nginx脚本-start、stop、reload…
2014/08/03 PHP
CentOS 6.3下安装PHP xcache扩展模块笔记
2014/09/10 PHP
php保存任意网络图片到服务器的方法
2015/04/14 PHP
分享五个PHP7性能优化提升技巧
2015/12/07 PHP
利用PHP命令行模式采集股票趋势信息
2016/08/09 PHP
Yii框架引用插件和ckeditor中body与P标签去除的方法
2017/01/19 PHP
jQuery帮助之CSS尺寸(五)outerHeight、outerWidth
2009/11/14 Javascript
innerHTML与jquery里的html()区别介绍
2012/10/12 Javascript
异步动态加载js与css文件的js代码
2013/09/15 Javascript
使用js实现数据格式化
2014/12/03 Javascript
bootstrap table 服务器端分页例子分享
2015/02/10 Javascript
详谈jQuery Ajax(load,post,get,ajax)的用法
2017/03/02 Javascript
vue多种弹框的弹出形式的示例代码
2017/09/18 Javascript
vue实现简单的MVVM框架
2018/08/05 Javascript
Vue 使用formData方式向后台发送数据的实现
2019/04/14 Javascript
element-ui tree结构实现增删改自定义功能代码
2020/08/31 Javascript
python爬虫之百度API调用方法
2017/06/11 Python
mac 安装python网络请求包requests方法
2018/06/13 Python
Python 常用模块 re 使用方法详解
2019/06/06 Python
python 执行终端/控制台命令的例子
2019/07/12 Python
Django在admin后台集成TinyMCE富文本编辑器的例子
2019/08/09 Python
Python字符串处理的8招秘籍(小结)
2019/08/13 Python
tensorflow 实现打印pb模型的所有节点
2020/01/23 Python
Python如何将图像音视频等资源文件隐藏在代码中(小技巧)
2020/02/16 Python
Python表达式的优先级详解
2020/02/18 Python
浅谈Pytorch torch.optim优化器个性化的使用
2020/02/20 Python
CSS3 二级导航菜单的制作的示例
2018/04/02 HTML / CSS
养牛场项目建议书
2014/05/13 职场文书
国际贸易毕业生自荐书
2014/06/22 职场文书
运动会闭幕式主持词
2015/07/01 职场文书
母婴行业实体、电商模式全面解析
2019/08/01 职场文书