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中this的使用说明
Sep 06 Javascript
jquery插件开发之实现google+圈子选择功能
Mar 10 Javascript
瀑布流布局代码一例
Apr 11 Javascript
使用phantomjs进行网页抓取的实现代码
Sep 29 Javascript
js实例属性和原型属性示例详解
Nov 23 Javascript
javaScript的函数对象的声明详解
Feb 06 Javascript
js控制网页前进和后退的方法
Jun 08 Javascript
JavaScript中三种异步上传文件方式
Mar 06 Javascript
终于实现了!精彩的jquery弹幕效果
Jul 18 Javascript
微信小程序进行微信支付的步骤昂述
Dec 01 Javascript
微信小程序 动态绑定事件并实现事件修改样式
Apr 13 Javascript
微信小程序商城项目之侧栏分类效果(1)
Apr 17 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
laravel5环境隐藏index.php后缀(apache)的方法
2019/10/12 PHP
在JavaScript中通过URL传递汉字的方法
2007/04/09 Javascript
document.forms用法示例介绍
2014/06/26 Javascript
javascript实现多栏闭合展开式广告位菜单效果实例
2015/08/05 Javascript
js密码强度检测
2016/01/07 Javascript
学习Javascript闭包(Closure)知识
2016/08/07 Javascript
写给小白看的JavaScript异步
2017/11/29 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
2017/12/05 Javascript
Node.js readline 逐行读取、写入文件内容的示例
2018/03/01 Javascript
从0到1搭建element后台框架优化篇(打包优化)
2019/05/12 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
Vue中常用rules校验规则(实例代码)
2019/11/14 Javascript
详解Vue数据驱动原理
2020/11/17 Javascript
Vue实现多页签组件
2021/01/14 Vue.js
[02:32]DOTA2完美大师赛场馆静安体育中心观赛全攻略
2017/11/08 DOTA
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python3.x版本中新的字符串格式化方法
2015/04/24 Python
在Python中使用HTMLParser解析HTML的教程
2015/04/29 Python
Python动刷新抢12306火车票的代码(附源码)
2018/01/24 Python
Python编程scoketServer实现多线程同步实例代码
2018/01/29 Python
python 对dataframe下面的值进行大规模赋值方法
2018/06/09 Python
详解python 3.6 安装json 模块(simplejson)
2019/04/02 Python
python爬虫豆瓣网的模拟登录实现
2019/08/21 Python
flask 框架操作MySQL数据库简单示例
2020/02/02 Python
pyecharts调整图例与各板块的位置间距实例
2020/05/16 Python
Python多个装饰器的调用顺序实例解析
2020/05/22 Python
Python 实现键盘鼠标按键模拟
2020/11/18 Python
使用CSS3实现一个3D相册效果实例
2016/12/03 HTML / CSS
法国家具及室内配件店:home24
2017/01/21 全球购物
Made in Design英国:设计家具、照明、家庭装饰和花园家具
2019/09/24 全球购物
客户经理竞聘演讲稿
2014/05/15 职场文书
党员学习中共十八大报告思想汇报
2014/09/15 职场文书
python for循环赋值问题
2021/06/03 Python
MySQL连表查询分组去重的实现示例
2021/07/01 MySQL
详解Java七大阻塞队列之SynchronousQueue
2021/09/04 Java/Android
Mysql中常用的join连接方式
2022/05/11 MySQL