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 相关文章推荐
JavaScript Event学习第六章 事件的访问
Feb 07 Javascript
Jquery下:nth-child(an+b)的使用注意
May 28 Javascript
js open() 与showModalDialog()方法使用介绍
Sep 10 Javascript
js 将json字符串转换为json对象的方法解析
Nov 13 Javascript
使用JavaScript判断图片是否加载完成的三种实现方式
May 04 Javascript
DOM基础教程之使用DOM
Jan 19 Javascript
浅析JavaScript事件和方法
Feb 28 Javascript
chrome浏览器当表单自动填充时如何去除浏览器自动添加的默认样式
Oct 09 Javascript
原生js实现移动端瀑布流式代码示例
Dec 18 Javascript
angular2中Http请求原理与用法详解
Jan 11 Javascript
使用flow来规范javascript的变量类型
Sep 12 Javascript
解决ant design vue中树形控件defaultExpandAll设置无效的问题
Oct 26 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小马小结(方便查找后门的朋友)
2012/05/05 PHP
PHP中key和current,next的联合运用实例分析
2016/03/29 PHP
php遍历、读取文件夹中图片并分页显示图片的方法
2016/11/15 PHP
原生PHP实现导出csv格式Excel文件的方法示例【附源码下载】
2019/03/07 PHP
laravel model模型处理之修改查询或修改字段时的类型格式案例
2019/10/17 PHP
Prototype1.5 rc2版指南最后一篇之Position
2007/01/10 Javascript
ExtJs GridPanel简单的增删改实现代码
2010/08/26 Javascript
仿谷歌主页js动画效果实现代码
2013/07/14 Javascript
图片上传判断及预览脚本的效果实例
2013/08/07 Javascript
浅谈JavaScript中Date(日期对象),Math对象
2015/02/05 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
2016/01/12 Javascript
ES6的新特性概览
2016/03/10 Javascript
JS全局变量和局部变量最新解析
2016/06/24 Javascript
利用webstrom调试Vue.js单页面程序的方法教程
2017/06/06 Javascript
ES6中新增的Object.assign()方法详解
2017/09/22 Javascript
微信小程序跨页面数据传递事件响应实现过程解析
2019/12/19 Javascript
Vue优化:常见会导致内存泄漏问题及优化详解
2020/08/04 Javascript
python生成随机密码或随机字符串的方法
2015/07/03 Python
python使用RNN实现文本分类
2018/05/24 Python
Python操作MySQL数据库的方法
2018/06/20 Python
Python实现的统计文章单词次数功能示例
2019/07/08 Python
python实现猜拳小游戏
2020/04/05 Python
Python Pandas 转换unix时间戳方式
2019/12/07 Python
基于python3的socket聊天编程
2020/02/17 Python
关于jupyter打开之后不能直接跳转到浏览器的解决方式
2020/04/13 Python
CSS3弹性布局内容对齐(justify-content)属性使用详解
2017/07/31 HTML / CSS
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
澳大利亚家居用品零售商:Harris Scarfe
2020/10/10 全球购物
求职自荐书范文
2013/12/04 职场文书
商务经理岗位职责
2014/07/30 职场文书
租房安全协议书
2014/08/20 职场文书
党员群众路线个人整改措施思想汇报
2014/10/12 职场文书
夫妻双方自愿离婚协议书怎么写
2014/12/01 职场文书
北京英语导游词
2015/02/12 职场文书
高中信息技术教学反思
2016/02/16 职场文书
2019升学宴主持词范本5篇
2019/10/09 职场文书