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 回车提交表单两种实现方法
Dec 31 Javascript
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
Aug 15 Javascript
JQuery实现鼠标移动图片显示描述层的方法
Jun 25 Javascript
jQuery的事件委托实例分析
Jul 15 Javascript
jQuery简单实现MD5加密的方法
Mar 03 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
Aug 19 Javascript
微信小程序仿知乎实现评论留言功能
Nov 28 Javascript
js中对象和面向对象与Json介绍
Jan 21 Javascript
微信小程序学习笔记之文件上传、下载操作图文详解
Mar 29 Javascript
优雅的处理vue项目异常实战记录
Jun 05 Javascript
JS使用H5实现图片预览功能
Sep 30 Javascript
浅谈JavaScript中等号、双等号、 三等号的区别
Aug 06 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结合正则批量抓取网页中邮箱地址
2015/05/19 PHP
如何解决phpmyadmin导入数据库文件最大限制2048KB
2015/10/09 PHP
详解WordPress开发中wp_title()函数的用法
2016/01/07 PHP
PHP+swoole实现简单多人在线聊天群发
2016/01/19 PHP
Phpstorm+Xdebug断点调试PHP的方法
2018/05/14 PHP
统计出现最多的字符次数的js代码
2010/12/03 Javascript
jQuery bind事件使用详解
2011/05/05 Javascript
javascript的原生方法获取数组中的最大(最小)值
2012/12/19 Javascript
地址栏传递中文参数乱码在js里用escape转码
2013/08/28 Javascript
jquery.ui.draggable中文文档(原文翻译)
2013/11/15 Javascript
点击按钮自动加关注的代码(sina微博/QQ空间/人人网/腾讯微博)
2014/01/02 Javascript
javascript实现tab响应式切换特效
2016/01/29 Javascript
JS版微信6.0分享接口用法分析
2016/10/13 Javascript
js querySelector() 使用方法
2016/12/21 Javascript
Vue.js 2.0中select级联下拉框实例
2017/03/06 Javascript
jquery实现的table排序功能示例
2017/03/10 Javascript
Vue-Router的使用方法
2018/09/05 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
[38:39]KG vs Mineski 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
python实现自主查询实时天气
2018/06/22 Python
Python面向对象程序设计示例小结
2019/01/30 Python
浅谈Python 敏感词过滤的实现
2019/08/15 Python
关于pytorch多GPU训练实例与性能对比分析
2019/08/19 Python
Python反爬虫伪装浏览器进行爬虫
2020/02/28 Python
Python 去除字符串中指定字符串
2020/03/05 Python
使用html2canvas实现将html内容写入到canvas中生成图片
2020/01/03 HTML / CSS
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
电子信息工程专业推荐信
2014/02/14 职场文书
采购类个人求职的自我评价
2014/02/18 职场文书
竞聘书模板
2014/03/31 职场文书
初中英语课后反思
2014/04/25 职场文书
不同意离婚上诉状
2015/05/23 职场文书
总经理致辞
2015/07/29 职场文书
2019入党申请书格式和范文
2019/06/25 职场文书
jquery插件实现代码雨特效
2021/04/24 jQuery
解决Maven项目中 Invalid bound statement 无效的绑定问题
2021/06/15 Java/Android