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实现动态CSS换肤技术的脚本
Jun 29 Javascript
JavaScript国旗变换效果代码
Aug 13 Javascript
Firefox getBoxObjectFor getBoundingClientRect联系
Oct 26 Javascript
jquery简单实现幻灯片的方法
Aug 03 Javascript
函数四种调用模式以及其中的this指向
Jan 16 Javascript
Vue组件化通讯的实例代码
Jun 23 Javascript
jQuery使用bind函数实现绑定多个事件的方法
Oct 11 jQuery
vue指令只能输入正数并且只能输入一个小数点的方法
Jun 08 Javascript
微信小程序实现列表页的点赞和取消点赞功能
Nov 02 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
Apr 28 Javascript
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
Jun 18 jQuery
vue实现同时设置多个倒计时
May 20 Vue.js
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文件
2007/01/04 PHP
php强制下载文件函数
2016/08/24 PHP
PHP实现的常规正则验证helper公共类完整实例
2017/04/27 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
javascript实现划词标记+划词搜索功能
2007/03/06 Javascript
Javascript的一种模块模式
2008/03/22 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
2013/04/11 Javascript
js window.open弹出新的网页窗口
2014/01/16 Javascript
JS实用的动画弹出层效果实例
2015/05/05 Javascript
基于Jquery和html5的7款个性化地图插件
2015/11/17 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
2016/02/18 Javascript
AngularJS 表达式详细讲解及实例代码
2016/07/26 Javascript
AngularJS指令与控制器之间的交互功能示例
2016/12/14 Javascript
angularjs使用directive实现分页组件的示例
2017/02/07 Javascript
jQuery插件zTree实现获取一级节点数据的方法
2017/03/08 Javascript
js遍历json对象所有key及根据动态key获取值的方法(必看)
2017/03/09 Javascript
jQuery实现按比例缩放图片的方法
2017/04/29 jQuery
javascript连接mysql与php通过odbc连接任意数据库的实例
2017/12/27 Javascript
async/await优雅的错误处理方法总结
2019/01/30 Javascript
angular中如何绑定iframe中src的方法
2019/02/01 Javascript
vue表单数据交互提交演示教程
2019/11/13 Javascript
JS实现省市县三级下拉联动
2020/04/10 Javascript
JavaScript中变量提升和函数提升的详解
2020/08/07 Javascript
[10:54]Team Spirit vs Navi
2018/06/07 DOTA
python读取txt文件,去掉空格计算每行长度的方法
2018/12/20 Python
基于Python函数和变量名解析
2019/07/19 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
如何基于Python实现数字类型转换
2020/02/07 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
tensorflow常用函数API介绍
2020/04/19 Python
python3中calendar返回某一时间点实例讲解
2020/11/18 Python
微软俄罗斯官方网站:Microsoft俄罗斯
2016/09/18 全球购物
缓解脚、腿和背部疼痛:Z-CoiL鞋
2019/03/12 全球购物
中医临床专业自我鉴定范文
2014/01/15 职场文书
网吧温馨提示
2015/07/17 职场文书
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
2021/04/14 Python