js 原型对象和原型链理解


Posted in Javascript onFebruary 09, 2017

一个例子让你彻底明白原型对象和原型链

开篇

之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)的解释去描述。有一句话说的好:如果你不能把一个很复杂的东西用最简单的话语描述出来,那就说明你没有真正的理解。最近正在读《Javascript高级程序设计》,书中对原型对象和原型链的描述让我受益匪浅,下面仅用一个对比性的例子来说明。

我们经常会这么写

function Person () {
 this.name = 'John';
 }
 var person = new Person();
 Person.prototype.say = function() {
 console.log('Hello,' + this.name);
 };
 person.say();//Hello,John

上述代码非常简单,Person原型对象定义了公共的say方法,虽然此举在构造实例之后出现,但因为原型方法在调用之前已经声明,因此之后的每个实例将都拥有该方法。从这个简单的例子里,我们可以得出:

原型对象的用途是为每个实例对象存储共享的方法和属性,它仅仅是一个普通对象而已。并且所有的实例是共享同一个原型对象,因此有别于实例方法或属性,原型对象仅有一份。所有就会有如下等式成立:

person.say == new Person().say

可能我们也会这么写

function Person () {
 this.name = 'John';
 }
 var person = new Person();
 Person.prototype = {
 say: function() {
  console.log('Hello,' + this.name);
 }
 };
 person.say();//person.say is not a function

很不幸,person.say方法没有找到,所以报错了。其实这样写的初衷是好的:因为如果想在原型对象上添加更多的属性和方法,我们不得不每次都要写一行Person.prototype,还不如提炼成一个Object来的直接。但是此例子巧就巧在构造实例对象操作是在添加原型方法之前,这样就会造成一个问题:

当var person = new Person()时,Person.prototype为:Person {}(当然了,内部还有constructor属性),即Person.prototype指向一个空的对象{}。而对于实例person而言,其内部有一个原型链指针proto,该指针指向了Person.prototype指向的对象,即{}。接下来重置了Person的原型对象,使其指向了另外一个对象,即

Object {say: function},

这时person.proto的指向还是没有变,它指向的{}对象里面是没有say方法的,因为报错。

从这个现象我们可以得出:

在js中,对象在调用一个方法时会首先在自身里寻找是否有该方法,若没有,则去原型链上去寻找,依次层层递进,这里的原型链就是实例对象的__proto__属性。

若想让上述例子成功运行,最简单有效的方法就是交换构造对象和重置原型对象的顺序,即:

function Person () {
 this.name = 'John';
 }
 Person.prototype = {
 say: function() {
  console.log('Hello,' + this.name);
 }
 };
 var person = new Person();
 person.say();//person.say is not a function

一张图让你秒懂原型链

js 原型对象和原型链理解

其实,只需要明白原型对象的结构即可:

Function.prototype = {
 constructor : Function,
 __proto__ : parent prototype,
 some prototype properties: ...
 };

总结:函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针__proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直指向Object的原型对象上,而Object的原型对象用Object.__proto__ = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
JS是否可以跨文件同时控制多个iframe页面的应用技巧
Dec 16 Javascript
IE浏览器打印的页眉页脚设置解决方法
Dec 08 Javascript
JQuery 常用方法和事件详细介绍
Apr 18 Javascript
js实现checkbox全选、不选与反选的方法
Feb 09 Javascript
javascript实现图片循环渐显播放的方法
Feb 24 Javascript
JavaScript实现当网页加载完成后执行指定函数的方法
Mar 21 Javascript
Jquery easyui 实现动态树
Nov 17 Javascript
AngularJS用户选择器指令实例分析
Nov 04 Javascript
基于BootStrap与jQuery.validate实现表单提交校验功能
Dec 22 Javascript
JavaScript中 DOM操作方法小结
Apr 25 Javascript
Nautil 中使用双向数据绑定的实现
Oct 02 Javascript
浅析js实现网页截图的两种方式
Nov 01 Javascript
AngularJs表单校验功能实例代码
Feb 09 #Javascript
javascript 显示全局变量与隐式全局变量的区别
Feb 09 #Javascript
JS获取本周周一,周末及获取任意时间的周一周末功能示例
Feb 09 #Javascript
简单谈谈Javascript函数中的arguments
Feb 09 #Javascript
javascript 中设置window.location.href跳转无效问题解决办法
Feb 09 #Javascript
微信小程序之picker日期和时间选择器
Feb 09 #Javascript
BootStrap 弹出层代码
Feb 09 #Javascript
You might like
zend optimizer在wamp的基础上安装图文教程
2013/10/26 PHP
php动态生成函数示例
2014/03/21 PHP
Yii使用ajax验证显示错误messagebox的解决方法
2014/12/03 PHP
php安装swoole扩展的方法
2015/03/19 PHP
详解ThinkPHP3.2.3验证码显示、刷新、校验
2016/12/29 PHP
JS读取cookies信息(记录用户名)
2012/01/10 Javascript
探寻Javascript执行效率问题
2014/11/12 Javascript
Javascript中的高阶函数介绍
2015/03/15 Javascript
js实现图片点击左右轮播
2015/07/08 Javascript
jQuery实现倒计时(倒计时年月日可自己输入)
2016/12/02 Javascript
js判断是否是手机页面
2017/03/17 Javascript
JavaScript实现动态添加Form表单元素的方法示例
2017/08/14 Javascript
在原生不支持的旧环境中添加兼容的Object.keys实现方法
2017/09/11 Javascript
JS实现的集合去重,交集,并集,差集功能示例
2018/03/13 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
layui禁用侧边导航栏点击事件的解决方法
2019/09/25 Javascript
微信内置浏览器图片查看器的代码实例
2019/10/08 Javascript
TypeScript高级用法的知识点汇总
2019/12/17 Javascript
Javascript地址引用代码实例解析
2020/02/25 Javascript
浅谈vue中get请求解决传输数据是数组格式的问题
2020/08/03 Javascript
[05:29]2014DOTA2国际邀请赛 赛后专访:LGDNewbee顺利过关
2014/07/13 DOTA
python获取一组数据里最大值max函数用法实例
2015/05/26 Python
python中json格式数据输出的简单实现方法
2016/10/31 Python
Python中functools模块函数解析
2017/03/12 Python
Python双精度浮点数运算并分行显示操作示例
2017/07/21 Python
PyQt5下拉式复选框QComboCheckBox的实例
2019/06/25 Python
利用Python实现kNN算法的代码
2019/08/16 Python
深入浅析Python科学计算库Scipy及安装步骤
2019/10/12 Python
对python中各个response的使用说明
2020/03/28 Python
Quiksilver美国官网:始于1969年的优质冲浪服和滑雪板外套
2020/04/20 全球购物
多媒体编辑专业毕业生推荐信
2013/11/05 职场文书
教师三严三实学习心得体会
2014/10/11 职场文书
邀请书模板
2015/02/02 职场文书
2015年监理个人工作总结
2015/05/23 职场文书
机器人总动员观后感
2015/06/09 职场文书
react antd实现动态增减表单
2021/06/03 Javascript