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创建自己的插件(自定义插件)的方法
Jun 10 Javascript
String.prototype实现的一些javascript函数介绍
Nov 22 Javascript
js继承call()和apply()方法总结
Dec 08 Javascript
jQuery文字横向滚动效果的实现代码
May 31 Javascript
对javascript继承的理解
Oct 11 Javascript
AngularJS入门教程之模块化操作用法示例
Nov 02 Javascript
微信小程序 新建登录页并实现tabBar隐藏
Jun 13 Javascript
Vue.js 单页面多路由区域操作的实例详解
Jul 17 Javascript
javascript实现考勤日历功能
Nov 29 Javascript
vue + typescript + 极验登录验证的实现方法
Jun 27 Javascript
JS实现多选框的操作
Jun 24 Javascript
vscode中Vue别名路径提示的实现
Jul 31 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/11/25 PHP
PHP中time(),date(),mktime()区别介绍
2013/09/28 PHP
PHP实现数字补零功能的2个函数介绍
2014/05/12 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
非常有用的9个PHP代码片段
2016/04/06 PHP
PHP三种方式实现链式操作详解
2017/01/21 PHP
laravel框架实现后台登录、退出功能示例
2019/10/31 PHP
JavaScript Event事件学习第一章 Event介绍
2010/02/07 Javascript
js列举css中所有图标的实现代码
2011/07/04 Javascript
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
js检测网络是否具体连接功能的代码
2014/05/23 Javascript
jquery图片倾斜层叠切换特效代码分享
2015/08/27 Javascript
JavaScript+CSS实现仿Mootools竖排弹性动画菜单效果
2015/10/14 Javascript
JavaScript中字符串与Unicode编码互相转换的实现方法
2015/12/18 Javascript
javascript实现表单验证
2016/01/29 Javascript
如何使用jquery实现文字上下滚动效果
2016/10/12 Javascript
详解jQuery停止动画——stop()方法的使用
2016/12/14 Javascript
微信小程序实现换肤功能
2018/03/14 Javascript
vue异步axios获取的数据渲染到页面的方法
2018/08/09 Javascript
mpvue中使用flyjs全局拦截的实现代码
2018/09/13 Javascript
浅析Vue下的components模板使用及应用
2019/11/27 Javascript
vue 翻页组件vue-flip-page效果
2020/02/05 Javascript
JavaScript 实现拖拽效果组件功能(兼容移动端)
2020/11/11 Javascript
[01:11:48]Fnatic vs IG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python中快速进行多个字符替换的方法小结
2016/12/15 Python
解决Python运行文件出现out of memory框的问题
2018/12/03 Python
Python实现对字典分别按键(key)和值(value)进行排序的方法分析
2018/12/19 Python
Python内置random模块生成随机数的方法
2019/05/31 Python
tensorflow自定义激活函数实例
2020/02/04 Python
python爬虫库scrapy简单使用实例详解
2020/02/10 Python
Python3+selenium实现cookie免密登录的示例代码
2020/03/18 Python
Hudson Jeans官网:高级精制牛仔裤
2018/11/28 全球购物
写出二分查找算法的两种实现
2013/05/13 面试题
给校长的建议书300字
2014/05/16 职场文书
2015年学雷锋活动总结
2015/02/06 职场文书
JS如何使用剪贴板操作Clipboard API
2021/05/17 Javascript