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类 from qq
Nov 13 Javascript
Javascript显示和隐藏ul列表的方法
Jul 15 Javascript
Atitit.js的键盘按键事件捆绑and事件调度
Apr 01 Javascript
BootStrap智能表单实战系列(四)表单布局介绍
Jun 13 Javascript
最佳的JavaScript错误处理实践
Jul 16 Javascript
AngularJS ng-mousedown 指令
Aug 02 Javascript
input file上传 图片预览功能实例代码
Oct 25 Javascript
JSON与js对象序列化实例详解
Mar 16 Javascript
使用 vue.js 构建大型单页应用
Feb 10 Javascript
vue中添加mp3音频文件的方法
Mar 02 Javascript
jQuery内容选择器与表单选择器实例分析
Jun 28 jQuery
Javascript执行上下文顺序的深入讲解
Nov 04 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
THINKPHP内容分页代码分享
2015/01/14 PHP
ThinkPHP中order()使用方法详解
2016/04/19 PHP
php workerman定时任务的实现代码
2018/12/23 PHP
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
2007/01/09 Javascript
js实现鼠标划过给div加透明度的方法
2015/05/25 Javascript
Nodejs Express4.x开发框架随手笔记
2015/11/23 NodeJs
基于jquery实现智能表单验证操作
2016/05/09 Javascript
基于jquery实现三级下拉菜单
2016/05/10 Javascript
基于Bootstrap实现tab标签切换效果
2020/04/15 Javascript
深入浅析JavaScript中的3DES
2016/08/24 Javascript
jQuery动态修改字体大小的方法【测试可用】
2016/09/09 Javascript
基于JavaScript实现评论框展开和隐藏功能
2017/08/25 Javascript
vue中实现在外部调用methods的方法(推荐)
2018/02/08 Javascript
详解vue2.0 不同屏幕适配及px与rem转换问题
2018/02/23 Javascript
解决vue-cli3 使用子目录部署问题
2018/07/19 Javascript
微信小程序实现授权登录
2019/05/15 Javascript
js实现星星海特效的示例
2020/09/28 Javascript
在vue中使用jsonp进行跨域请求接口操作
2020/10/29 Javascript
遍历python字典几种方法总结(推荐)
2016/09/11 Python
解决pyecharts在jupyter notebook中使用报错问题
2020/04/23 Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
2019/11/16 Python
详解CSS3 rem(设置字体大小) 教程
2017/11/21 HTML / CSS
HTML5 图片预加载的示例代码
2020/03/25 HTML / CSS
Expedia爱尔兰:酒店、机票、租车及廉价假期
2017/01/02 全球购物
Chi Chi London官网:购买连衣裙和礼服
2020/10/25 全球购物
什么是lambda函数
2013/09/17 面试题
《孔子游春》教学反思
2014/02/25 职场文书
大学四年个人的自我评价
2014/02/26 职场文书
洗手间标语
2014/06/23 职场文书
乡党委干部党的群众路线教育实践活动个人对照检查材料思想汇报
2014/10/01 职场文书
委托证明范本
2014/11/25 职场文书
2014年圣诞节寄语
2014/12/08 职场文书
2016小学教师读书心得体会
2016/01/13 职场文书
CSS3通过var()和calc()函数实现动画特效
2021/03/30 HTML / CSS
Python读取和写入Excel数据
2022/04/20 Python
搭建Yolov5服务器
2022/04/30 Servers