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 相关文章推荐
使用滤镜设置透明导致 IE 6/7/8/9 解析异常的解决方法
Apr 07 Javascript
jQuery DOM操作实例
Mar 05 Javascript
通过Jquery的Ajax方法读取将table转换为Json
May 31 Javascript
推荐6款基于jQuery实现图片效果插件
Dec 07 Javascript
Javascript基础教程之while语句
Jan 18 Javascript
json对象与数组以及转换成js对象的简单实现方法
Jun 24 Javascript
JS中使用DOM来控制HTML元素
Jul 31 Javascript
扩展bootstrap的modal模态框-动态添加modal框-弹出多个modal框
Feb 21 Javascript
ztree实现左边动态生成树右边为内容详情功能
Nov 03 Javascript
javascript实现获取一个日期段内每天不同的价格(计算入住总价格)
Feb 05 Javascript
vue2过滤器模糊查询方法
Sep 16 Javascript
搭建vscode+vue环境的详细教程
Aug 31 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
PHP和.net中des加解密的实现方法
2013/02/27 PHP
如何使用PHP实现javascript的escape和unescape函数
2013/06/29 PHP
PHP实现登录验证码校验功能
2018/05/17 PHP
laravel解决迁移文件一次删除创建字段报错的问题
2019/10/24 PHP
判断JS对象是否拥有某种属性的两种方式
2013/12/02 Javascript
JQuery教学之性能优化
2014/05/14 Javascript
jquery制作漂亮的弹出层提示消息特效
2014/12/23 Javascript
jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象
2016/01/23 Javascript
javascript的函数劫持浅析
2016/09/26 Javascript
JS+HTML5实现上传图片预览效果完整实例【测试可用】
2017/04/20 Javascript
node.js中grunt和gulp的区别详解
2017/07/17 Javascript
浅谈angular表单提交中ng-submit的默认使用方法
2018/09/30 Javascript
vue中eslintrc.js配置最详细介绍
2018/12/21 Javascript
ES2020 新特性(种草)
2020/01/12 Javascript
javascript设计模式 ? 适配器模式原理与应用实例分析
2020/04/13 Javascript
[51:34]Ti4主赛事胜者组 DK vs EG 2
2014/07/19 DOTA
[05:08]2014DOTA2国际邀请赛 Hao专访复仇的胜利很爽
2014/07/15 DOTA
Python random模块常用方法
2014/11/03 Python
Python3 处理JSON的实例详解
2017/10/29 Python
使用pycharm在本地开发并实时同步到服务器
2019/08/02 Python
python生成特定分布数的实例
2019/12/05 Python
Python使用requests xpath 并开启多线程爬取西刺代理ip实例
2020/03/06 Python
详解python tcp编程
2020/08/24 Python
pycharm + django跨域无提示的解决方法
2020/12/06 Python
css3实现的下拉菜单效果示例
2014/01/22 HTML / CSS
html5 css3实例教程 一款html5和css3实现的小机器人走路动画
2014/10/20 HTML / CSS
阿根廷票务网站:StubHub阿根廷
2018/04/13 全球购物
Kivari官网:在线购买波西米亚服装
2018/10/29 全球购物
橄榄树药房:OLIVEDA
2019/09/01 全球购物
军训自我鉴定范文
2014/02/13 职场文书
检讨书大全
2015/01/27 职场文书
郭明义电影观后感
2015/06/08 职场文书
电影雨中的树观后感
2015/06/15 职场文书
Anaconda配置各版本Pytorch的实现
2021/08/07 Python
Linux中一对多配置日志服务器的详细步骤
2022/07/23 Servers
Python  序列化反序列化和异常处理的问题小结
2022/12/24 Python