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 27 Javascript
JS的Document属性和方法小结
Sep 17 Javascript
javascript从右边截取指定字符串的三种实现方法
Nov 29 Javascript
表单序列化与jq中的serialize使用示例
Feb 21 Javascript
jQuery设置指定网页元素宽度和高度的方法
Mar 25 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
Nov 21 Javascript
bootstrap table 多选框分页保留示例代码
Mar 08 Javascript
angular内置provider之$compileProvider详解
Sep 27 Javascript
vue.js element-ui tree树形控件改iview的方法
Mar 29 Javascript
vue router 源码概览案例分析
Oct 09 Javascript
又拍云 Node.js 实现文件上传、删除功能
Oct 28 Javascript
JQuery基于FormData异步提交数据文件
Sep 01 jQuery
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也能干大事 随机函数
2015/04/14 PHP
Swoole 5将移除自动添加Event::wait()特性详解
2019/07/10 PHP
jquery 获取json数据实现代码
2009/04/27 Javascript
Chrome中JSON.parse的特殊实现
2011/01/12 Javascript
jsvascript图像处理—(计算机视觉应用)图像金字塔
2013/01/15 Javascript
document.createElement()用法及注意事项(ff下不兼容)
2013/03/13 Javascript
php和js对数据库图片进行等比缩放示例
2014/04/28 Javascript
浅谈JavaScript实现面向对象中的类
2014/12/09 Javascript
JS HTML5实现拖拽移动列表效果
2020/08/27 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
vue项目实战总结篇
2018/02/11 Javascript
详解webpack打包时排除其中一个css、js文件或单独打包一个css、js文件(两种方法)
2018/10/26 Javascript
微信打开网址添加在浏览器中打开提示的办法
2019/05/20 Javascript
JS实现数组删除指定元素功能示例
2019/06/05 Javascript
微信小程序bindtap事件与冒泡阻止详解
2019/08/08 Javascript
Angular 中使用 FineReport不显示报表直接打印预览
2019/08/21 Javascript
Vue插件之滑动验证码
2019/09/21 Javascript
聊聊Vue中provide/inject的应用详解
2019/11/10 Javascript
js代码实现轮播图
2020/05/04 Javascript
python实现的重启关机程序实例
2014/08/21 Python
python如何爬取个性签名
2018/06/19 Python
pandas 透视表中文字段排序方法
2018/11/16 Python
pytorch多进程加速及代码优化方法
2019/08/19 Python
利用pandas合并多个excel的方法示例
2019/10/10 Python
Python如何操作office实现自动化及win32com.client的运用
2020/04/01 Python
html5利用canvas绘画二级树形结构图的示例
2017/09/27 HTML / CSS
HTML5拖放功能_动力节点Java学院整理
2017/07/13 HTML / CSS
中国领先的专业演出票务网:永乐票务
2016/08/29 全球购物
澳大利亚手表品牌:Time IV Change
2018/10/06 全球购物
澳大利亚网上书店:QBD
2021/01/09 全球购物
解释DataSet(ds) 和 ds as DataSet 的含义
2014/07/27 面试题
乡镇党委书记第三阶段个人整改措施
2014/09/16 职场文书
横空出世观后感
2015/06/09 职场文书
运动会班级口号霸气押韵
2015/12/24 职场文书
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
2021/04/06 Python
Python实现Telnet自动连接检测密码的示例
2021/04/16 Python