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 相关文章推荐
很多人都是用下面的js刷新站IP和PV
Sep 05 Javascript
图片Slider 带左右按钮的js示例
Aug 30 Javascript
jquery css 设置table的奇偶行背景色示例
Jun 03 Javascript
JavaScript学习心得之概述
Jan 20 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
Dec 24 Javascript
微信小程序  自定义创建详细介绍
Oct 27 Javascript
jQuery简单实现遍历单选框的方法
Mar 06 Javascript
使用async await 封装 axios的方法
Jul 09 Javascript
Vue axios设置访问基础路径方法
Sep 19 Javascript
vue router动态路由设置参数可选问题
Aug 21 Javascript
JavaScript实现图片轮播特效
Oct 23 Javascript
axios如何取消重复无用的请求详解
Dec 15 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
Access数据库导入Mysql的方法之一
2006/10/09 PHP
PHP正确配置mysql(apache环境)
2011/08/28 PHP
PHP使用Pthread实现的多线程操作实例
2015/11/14 PHP
PHP 接入支付宝即时到账功能
2016/09/18 PHP
浅谈PHP SHA1withRSA加密生成签名及验签
2019/03/18 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
2019/08/14 PHP
php接口隔离原则实例分析
2019/11/11 PHP
javascript 处理HTML元素必须避免使用的一种方法
2009/07/30 Javascript
基于jQuery的图片左右无缝滚动插件
2012/05/23 Javascript
jQuery中filter()和find()的区别深入了解
2013/09/25 Javascript
JavaScript将字符串转换为整数的方法
2015/04/14 Javascript
JavaScript中Number.NEGATIVE_INFINITY值的使用详解
2015/06/05 Javascript
nodejs实现爬取网站图片功能
2017/12/14 NodeJs
jQuery序列化form表单数据为JSON对象的实现方法
2018/09/20 jQuery
JS闭包原理与应用经典示例
2018/12/20 Javascript
vue2.0自定义指令示例代码详解
2019/04/25 Javascript
微信小程序如何修改radio和checkbox的默认样式和图标
2019/07/24 Javascript
vue elementui 实现搜索栏公共组件封装的实例代码
2020/01/20 Javascript
如何基于js判断浏览器版本
2020/02/20 Javascript
[49:42]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#2Secret VS EG第一局
2016/03/04 DOTA
matplotlib作图添加表格实例代码
2018/01/23 Python
python3+PyQt5重新实现QT事件处理程序
2018/04/19 Python
使用Python 统计高频字数的方法
2019/01/31 Python
在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
2020/04/10 Python
PyCharm2020最新激活码+激活码补丁(亲测最新版PyCharm2020.2激活成功)
2020/11/25 Python
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
英国空调、除湿机和通风设备排名第一:Air Con Centre
2019/02/25 全球购物
一份全面的PHP面试问题考卷
2012/07/15 面试题
法律专业实习鉴定
2013/12/22 职场文书
小学生保护环境倡议书
2014/05/15 职场文书
工厂门卫的岗位职责
2014/07/27 职场文书
辞旧迎新演讲稿
2014/09/15 职场文书
采购部2015年度工作总结
2015/07/24 职场文书
2019暑假学生安全口号
2019/06/27 职场文书
Python OpenCV快速入门教程
2021/04/17 Python
python turtle绘图命令及案例
2021/11/23 Python