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 相关文章推荐
基于jQuery的左右滚动实现代码
Dec 03 Javascript
js随机颜色代码的多种实现方式
Apr 23 Javascript
JS分页效果示例
Oct 11 Javascript
Javascript WebSocket使用实例介绍(简明入门教程)
Apr 16 Javascript
js 通过html()及text()方法获取并设置p标签的显示值
May 14 Javascript
JSP中使用JavaScript动态插入删除输入框实现代码
Jun 13 Javascript
javascript实现的淘宝旅行通用日历组件用法实例
Aug 03 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
Feb 23 Javascript
去除字符串左右两边的空格(实现代码)
May 12 Javascript
jQuery异步提交表单的两种方式
Sep 13 Javascript
Node.js利用debug模块打印出调试日志的方法
Apr 25 Javascript
详解写好JS条件语句的5条守则
Feb 28 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简单的会话类代码
2011/08/08 PHP
php获取域名的google收录示例
2014/03/24 PHP
php 如何获取文件的后缀名
2016/06/05 PHP
jQuery DIV弹出效果实现代码
2009/07/03 Javascript
JQuery跨Iframe选择实现代码
2010/08/19 Javascript
javascript几个易错点记录
2014/11/26 Javascript
javascript 获取浏览器版本
2015/01/21 Javascript
javascript性能优化之事件委托实例详解
2015/12/12 Javascript
Google 地图API资料整理及详细介绍
2016/08/06 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
jQuery实现 RadioButton做必选校验功能
2017/06/15 jQuery
jQuery实现点击关注和取消功能
2017/07/03 jQuery
关于vue中 $emit的用法详解
2018/04/12 Javascript
vue 2.1.3 实时显示当前时间,每秒更新的方法
2018/09/16 Javascript
微信小程序用户位置权限的获取方法(拒绝后提醒)
2018/11/15 Javascript
vue实现图片上传预览功能
2019/12/23 Javascript
2019最新21个MySQL高频面试题介绍
2020/02/06 Javascript
[00:31]2016完美“圣”典风云人物:国士无双宣传片
2016/12/04 DOTA
详谈python http长连接客户端
2017/06/12 Python
python opencv之分水岭算法示例
2018/02/24 Python
Python使用sqlalchemy模块连接数据库操作示例
2019/03/13 Python
Python re 模块findall() 函数返回值展现方式解析
2019/08/09 Python
基于Python+Appium实现京东双十一自动领金币功能
2019/10/31 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
Django单元测试中Fixtures用法详解
2020/02/25 Python
详细分析Python可变对象和不可变对象
2020/07/09 Python
一款利用css3的鼠标经过动画显示详情特效的实例教程
2014/12/29 HTML / CSS
HTML5 File API改善网页上传功能
2009/08/19 HTML / CSS
NYX Professional Makeup英国官网:美国平价专业彩妆品牌
2019/11/13 全球购物
个人充满哲理的自我评价
2014/02/20 职场文书
12.4全国法制宣传日活动总结
2014/11/01 职场文书
个人总结格式范文
2015/03/09 职场文书
公司周年庆典致辞
2015/07/30 职场文书
幼儿园小班教育随笔
2015/08/14 职场文书
六年级作文之家庭作文
2019/12/12 职场文书
Python实现抖音热搜定时爬取功能
2022/03/16 Python