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提交并解析后台返回的XML的代码
Nov 03 Javascript
js常用代码段收集
Oct 28 Javascript
iframe窗口高度自适应的实现方法
Jan 08 Javascript
jQuery中noconflict函数的实现原理分解
Feb 03 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
Oct 22 Javascript
Bootstrap Fileinput文件上传组件用法详解
May 10 Javascript
Bootstrap 填充Json数据的实例代码
Jan 11 Javascript
微信小程序 devtool隐藏的秘密
Jan 21 Javascript
webpack入门+react环境配置
Feb 08 Javascript
基于JavaScript实现焦点图轮播效果
Mar 27 Javascript
jQuery 实现双击编辑表格功能
Jun 19 jQuery
原生JS实现获取及修改CSS样式的方法
Sep 04 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实现的oracle分页函数实例
2016/01/25 PHP
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
2011/09/27 Javascript
JQuery+DIV自定义滚动条样式的具体实现
2013/06/25 Javascript
微信小程序 生命周期详解
2016/10/12 Javascript
详解Javascript数据类型的转换规则
2016/12/12 Javascript
bootstrap导航条实现代码
2016/12/28 Javascript
javascript循环链表之约瑟夫环的实现方法
2017/01/16 Javascript
微信小程序中input标签详解及简单实例
2017/05/18 Javascript
ES6中数组array新增方法实例总结
2017/11/07 Javascript
JavaScript的setter与getter方法
2017/11/29 Javascript
原生js封装的ajax方法示例
2018/08/02 Javascript
深入理解 Koa 框架中间件原理
2018/10/18 Javascript
使用vuepress搭建静态博客的示例代码
2019/02/14 Javascript
如何实现vue的tree组件
2020/12/03 Vue.js
[35:34]Liquid vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python内置函数dir详解
2015/04/14 Python
简要讲解Python编程中线程的创建与锁的使用
2016/02/28 Python
Python自动化测试Eclipse+Pydev 搭建开发环境
2016/08/15 Python
Python中强大的命令行库click入门教程
2016/12/26 Python
Python中字符串格式化str.format的详细介绍
2017/02/17 Python
用python做一个搜索引擎(Pylucene)的实例代码
2017/07/05 Python
读取本地json文件,解析json(实例讲解)
2017/12/06 Python
利用TensorFlow训练简单的二分类神经网络模型的方法
2018/03/05 Python
对numpy中shape的深入理解
2018/06/15 Python
对Python正则匹配IP、Url、Mail的方法详解
2018/12/25 Python
Python多线程及其基本使用方法实例分析
2019/10/29 Python
python小项目之五子棋游戏
2019/12/26 Python
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
家用个人磨皮机:Trophy Skin
2017/03/30 全球购物
英国领先的杂志订阅网站:Magazine.co.uk
2018/01/25 全球购物
网上卖盒饭创业计划书范文
2014/02/07 职场文书
小学学校门卫岗位职责
2014/08/03 职场文书
小学教师师德师风自我剖析材料
2014/09/29 职场文书
刑事撤诉申请书
2015/05/18 职场文书
mysql定时自动备份数据库的方法步骤
2021/07/07 MySQL
在SQL Server中使用 Try Catch 处理异常的示例详解
2022/07/15 SQL Server