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实现兼容IE和FF的上下层的移动
May 04 Javascript
js实现鼠标点击文本框自动选中内容的方法
Aug 20 Javascript
在页面中输出当前客户端时间javascript实例代码
Mar 02 Javascript
jquery使用Cookie和JSON记录用户最近浏览历史
Apr 19 Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
Dec 08 Javascript
canvas实现简易的圆环进度条效果
Feb 28 Javascript
node.js实现回调的方法示例
Mar 01 Javascript
Angular使用动态加载组件方法实现Dialog的示例
May 11 Javascript
JS实现点击拉拽轮播图pc端移动端适配
Sep 05 Javascript
angular6根据environments配置文件更改开发所需要的环境的方法
Mar 06 Javascript
Vue Element UI + OSS实现上传文件功能
Jul 31 Javascript
微信小程序开发之获取用户手机号码(php接口解密)
May 17 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
超神学院:鹤熙已踏入神圣领域,实力不比凯莎弱
2020/03/02 国漫
php实现过滤字符串中的中文和数字实例
2015/07/29 PHP
利用PHP自动生成印有用户信息的名片
2016/08/01 PHP
thinkPHP5框架中widget的功能与用法详解
2018/06/11 PHP
PDO::beginTransaction讲解
2019/01/27 PHP
Gird事件机制初级读本
2007/03/10 Javascript
js DOM的学习笔记
2011/12/22 Javascript
JQuery设置和去除disabled属性的5种方法总结
2013/05/16 Javascript
jQuery+easyui中的combobox实现下拉框特效
2015/02/27 Javascript
jQuery检测滚动条是否到达底部
2015/12/15 Javascript
JavaScript 中 avalon绑定属性总结
2016/10/19 Javascript
React组件的三种写法总结
2017/01/12 Javascript
javascript 组合按键事件监听实现代码
2017/02/21 Javascript
JavaScript简单计算人的年龄示例
2017/04/15 Javascript
JS实现新建文件夹功能
2017/06/17 Javascript
深入探究node之Transform
2017/07/20 Javascript
JS+Ajax实现百度智能搜索框
2017/08/04 Javascript
微信小程序中使用wxss加载图片并实现动画效果
2018/08/13 Javascript
浅谈angular表单提交中ng-submit的默认使用方法
2018/09/30 Javascript
elementUI多选框反选的实现代码
2019/04/03 Javascript
详解小程序之简单登录注册表单验证
2019/05/13 Javascript
JS实现页面跳转与刷新的方法汇总
2019/08/30 Javascript
VUE页面中通过双击实现复制表格中内容的示例代码
2020/06/11 Javascript
Python实现队列的方法
2015/05/26 Python
Python pickle模块用法实例分析
2015/05/27 Python
详解python中Numpy的属性与创建矩阵
2018/09/10 Python
Python学习笔记之变量、自定义函数用法示例
2019/05/28 Python
如何使用scrapy中的ItemLoader提取数据
2020/09/30 Python
浅谈css3中的渐进增强和优雅降级
2017/12/01 HTML / CSS
HTML5 video播放器全屏(fullScreen)方法实例
2015/04/24 HTML / CSS
芭比波朗加拿大官方网站:Bobbi Brown Cosmetics CA
2020/11/05 全球购物
软件测试工程师笔试题带答案
2015/03/27 面试题
市委常委会班子党的群众路线教育实践活动整改方案
2014/10/25 职场文书
国庆庆典邀请函
2015/02/02 职场文书
闪闪红星观后感
2015/06/08 职场文书
mysql实现将字符串字段转为数字排序或比大小
2022/06/14 MySQL