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 相关文章推荐
防止网站内容被拷贝的一些方法与优缺点好处与坏处分析
Nov 30 Javascript
IE6下CSS图片缓存问题解决方法
Dec 09 Javascript
javascript实现保留两位小数的多种方法
Dec 18 Javascript
javascript判断firebug是否开启的方法
Nov 23 Javascript
前端自动化开发之Node.js的环境搭建教程
Apr 01 Javascript
javascript 初学教程及五子棋小程序的简单实现
Jul 04 Javascript
极简主义法编写JavaScript类
Nov 02 Javascript
浅谈MUI框架中加载外部网页或服务器数据的方法
Jan 31 Javascript
用Fundebug插件记录网络请求异常的方法
Feb 21 Javascript
vue改变对象或数组时的刷新机制的方法总结
Apr 24 Javascript
微信小程序 轮播图实现原理及优化详解
Sep 29 Javascript
vue中axios的二次封装实例讲解
Oct 14 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自动反斜杠的函数代码
2010/01/05 PHP
PHP __autoload函数(自动载入类文件)的使用方法
2012/02/04 PHP
PHP实现抓取迅雷VIP账号的方法
2015/07/30 PHP
yii2.0实现验证用户名与邮箱功能
2015/12/22 PHP
PHP Trait功能与用法实例分析
2020/06/03 PHP
Node.js 服务器端应用开发框架 -- Hapi.js
2014/07/29 Javascript
node.js中的favicon.ico请求问题处理
2014/12/15 Javascript
jQuery源码解读之addClass()方法分析
2015/02/20 Javascript
js实现精美的银灰色竖排折叠菜单
2015/05/16 Javascript
js去字符串前后空格的实现方法
2016/02/26 Javascript
微信小程序 教程之WXSS
2016/10/18 Javascript
AngularJS 中使用Swiper制作滚动图不能滑动的解决方法
2016/11/15 Javascript
jquery动态添加带有样式的HTML标签元素方法
2018/02/24 jQuery
Angular通过指令动态添加组件问题
2018/07/09 Javascript
详解JavaScript中精度失准问题及解决方法
2020/02/04 Javascript
javascript前端实现多视频上传
2020/12/13 Javascript
python time模块用法实例详解
2014/09/11 Python
跟老齐学Python之Python安装
2014/09/12 Python
将Python中的数据存储到系统本地的简单方法
2015/04/11 Python
详谈Pandas中iloc和loc以及ix的区别
2018/06/08 Python
python实现监控某个服务 服务崩溃即发送邮件报告
2018/06/21 Python
python 使用while写猜年龄小游戏过程解析
2019/10/07 Python
使用python的turtle绘画滑稽脸实例
2019/11/21 Python
Python基于wordcloud及jieba实现中国地图词云图
2020/06/09 Python
Python开发入门——迭代的基本使用
2020/09/03 Python
详解Python中第三方库Faker
2020/09/25 Python
GOOD AMERICAN官网:为曲线性感而设计
2017/12/28 全球购物
手工制作的意大利礼服鞋:Ace Marks
2018/12/15 全球购物
在线课程:Skillshare
2019/04/02 全球购物
为什么需要版本控制
2016/10/28 面试题
中学生民族团结演讲稿
2014/08/27 职场文书
2015年元旦文艺晚会总结(学院)
2014/11/28 职场文书
电话营销开场白
2015/05/29 职场文书
政协常委会议主持词
2015/07/03 职场文书
Java生成日期时间存入Mysql数据库的实现方法
2022/03/03 Java/Android
MySQL的意向共享锁、意向排它锁和死锁
2022/07/15 MySQL