一直以来对于JavaScript 的原型链的概念,始终有些东西有一种模糊感,最近刚好有时间就塌下心认真的把《JavaScript高级程序设计》中相关内容认真读了一遍,也查看了很多网上很多资料,以前很多不明白的地方也渐渐明白了起来。
写一篇文章记录一下最近学习的感悟。

字面量创建对象

我们通常创建一个对象无非就两种方式:

 1. var obj= new Object();//new 一个Object的实例2. var obj= {};//对象字面量
复制代码

使用对象字面量 和使用new的方式是一样的。 为了简便,一般推荐使用使用字面量:var o= {};

构造函数创建对象

当我们想要创建自定义的对象时,需要用到构造函数。 构造函数和普通函数有两个区别:
1. 便于和普通函数区分,函数名首字母大写。
2. 使用 new 操作符调用,返回一个实例对象。

除此之外和普通函数一摸一样。 我们使用构造函数Person来创建两个实例对象:

function Person(name){this.name = name;this.sayName= function (){ alert(this.name) }}
var person1 = new Person('小明');
var person2 = new Person('小红');
console.log(person1);//{name: "小明", sayName: fun}
console.log(person2);//{name: "小红", sayName: fun}
复制代码

上面的例子不难理解,虽然这两个实例对象都有sayName方法,而且他们两个的作用也是一样的,但却是两个方法,只是名字和作用一样。

画个图表示一下:

如果还不明白,我在打个比喻:
就像A街上有一间麦当劳,在B街上也开了一间麦当劳,它们都叫麦当劳,作用也是一样的。但是你总不能说他们是一间麦当劳吧?

person1.sayName === person2.sayName;//false
复制代码

如果这样的话,我们每构造出来一个对象,都要单独为这个对象创建出一个专属于它自己使用的sayName,这是很占用内存的。

那我们能不能让所有的实例对象都共同使用一个sayName方法,来节省内存,提升效率呢?这需要我们先理解原型对象的概念。

原型对象

我们先了解原型对象的概念。

每个对象都有原型对象(null除外),我们用__proto__表示,每个函数都有prototype属性,指向实例的原型对象。

对照这句话,按照我们上面的例子,也就是说Person.prototype指向person1的原型对象(__proto__),

Person.prototype === person1.__proto__; // true
复制代码

为了便于理解,来看一张图。

恩~他们的关系大概就是这样。

原型链

原型链简单用一句话概括就是:

原型链就是 对象的__proto__所连接的链状结构

为了方便我们理解原型链,举一个简单的例子:

function F(){this.a = 1;this.b = 2;
}
F.prototype.b = 3;
F.prototype.c = 4;
var o = new F();// {a: 1, b: 2}
//原型链:
//o --> o.__proto__ --> o.__proto__.__proto__ --> null
// 其中的 --> 就表示 __proto__ 也就是原型链
console.log(o.a); // 1
// o上有a这个属性吗?有的,该属性的值为1console.log(o.b); // 2
// o上有b这个属性吗?有的,该属性的值为2
// 原型上也有一个'b'属性,但是它不会被访问到.这种情况称为"属性遮蔽 "console.log(o.c); // 4
// o上有c这个属性吗?没有,那看看原型上有没有
// o.__proto__上有c这个属性吗?有的,该属性的值为4console.log(o.d); // undefined
// o上有d这个属性吗?没有,那看看原型上有没有
// o.__proto__ 上有d这个属性吗?没有,那看看它的原型上有没有
// o.__proto__.__proto__ 为 null,停止搜索
// 没有找到d属性,返回undefined。
复制代码

我们画张图来表示:

图中这条红色的线就是原型链。 由此可见,实例对象可访问自己原型对象上的属性和方法,额..准确来说是:

  1. 当一个对象 查找属性或方法时,自己有,停止查找,返回结果。
  2. 自己没有,顺着__proto__一直向上查找,如找到,停止查找,返回结果。
  3. 如果一直找到了原型链的最顶端(null),还没有找到,返回undefined

我们先回顾一下那个sayName的问题: 怎么让所有的实例对象都是用一个sayName方法呢
现在我们可以使用原型对象来解决这个问题了。
我们把sayName方法放到实例的原型对象上面,也就是Person.prototype上面来供所有实例使用:

function Person(name){this.name = name;}
Person.prototype.sayName=function (){alert(this.name);
}
var person1 = new Person('小明');
var person2 = new Person('小红');
person1.sayName === person2.sayName;//true
复制代码

用图表示:

补充

constructor
说一下我的经历,一开始理解原型链时,一直在prototype__proto__constructor在这个三个属性中绕来绕去。

为了便于理解,我把constructor放在最后了。
constructor字面意思就很容易理解,构造函数的意思。 一句话解释:

每个原型对象都有一个 constructor 属性指向 关联的构造函数。

还是上面那个例子:

console.log(Person.prototype.constructor);//Person(){ fun }
复制代码

需要注意的一点是,实例对象上没有constructor属性。 但是:

console.log(person1.constructor) ;//Person(){ fun }
复制代码

得出这个结果很简单: 实例上查找不到constructor属性 --> 顺着__proto__在原型对象上找 --> 找到并返回。

Object.prototype
刚才我们说了创建对象的两种方式:字面量创建对象和使用new操作符创建对象。
这两种方式创建出来的对象都会继承Object.prototyoe上的方法。 比如,我们使用字面量新创建一个对象o:

var o = {value: 1};
o.toString();//"[object Object]"
//查找过程: o --> o.__proto__ 找到返回
o.__proto__ === Object.prototype;//true
复制代码

o这个的对象本身并没有toString这个方法,但它却可以使用toString方法。
因为它继承了Object.prototyoe上的toString的方法。

null
既然对象都会继承自Object.prototype上面的方法,那它自己的原型又是什么呢。答案是null

Object.prototype.__prototype__ === null;//true
复制代码

以上仅自己学习所得,如有不当之处 望指出。

转载于:https://juejin.im/post/5c41a8de6fb9a049ba41dedb

新手理解的JS原型链相关推荐

  1. 新手理解的JS原型链 1

    一直以来对于JavaScript 的原型链的概念,始终有些东西有一种模糊感,最近刚好有时间就塌下心认真的把<JavaScript高级程序设计>中相关内容认真读了一遍,也查看了很多网上很多资 ...

  2. 简单粗暴地理解js原型链–js面向对象编程

    简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...

  3. 简述js原型链_简述js

    简述js原型链 (在React 16.8.0之前)((before React 16.8.0)) Yeah, I know that there are terabytes of data avail ...

  4. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

  5. 详解JS原型链与继承

    详解JS原型链与继承 JavaScript 目录 摘自JavaScript高级程序设计: 概念 确定原型和实例的关系 原型链的问题 借用构造函数 组合继承 原型继承 寄生式继承 寄生组合式继承 new ...

  6. 【JS】1339- 一文搞懂 JS 原型链的来龙去脉

    前言 在面向对象编程中,继承是非常实用也非常核心的功能,这一切都基于面向类语言中的类.然而,javascript和面向类的语言不同,它没有类作为蓝图,javascript中只有对象,但抽象继承思想又是 ...

  7. 从实现角度分析js原型链

    从实现角度分析js原型链 欢迎来我的博客阅读:<从实现角度分析js原型链> 网上介绍原型链的优质文章已经有很多了,比如说: https://github.com/mqyqingfeng/B ...

  8. JS原型链与instanceof底层原理

    转载自  JS原型链与instanceof底层原理 一.问题: instanceof 可以判断一个引用是否属于某构造函数: 另外,还可以在继承关系中用来判断一个实例是否属于它的父类型. 老师说:ins ...

  9. js原型链。。fuck

    js原型链..fuck function Person(name){this.name = name;};function Mother(){};//给mother提供公有的属性Mother.prot ...

最新文章

  1. 《Python从小白到大牛》第4章 Python语法基础
  2. iOS开发之--打印一堆奇怪东西的解决方案
  3. php 父类中获取子类的名称,php – 在父类中获取子类的名称(静态上下文)
  4. 链表(单链表、双链表、内核链表)
  5. Flex 4 [HostComponent] class xxx not found (AS code)
  6. 为PHP添加swoole异步并行扩展
  7. 阿里集团公布2022“研究型实习生”计划
  8. 2021全国大学生数学建模竞赛报名通知+试题+优秀论文
  9. Mysql源代码分析系列(1): 编译和调试--转载
  10. 单片机—外部中断与定时器 学习笔记
  11. Spring Initializr私服搭建和定制化模板
  12. 李飞飞论战《未来简史》作者赫拉利!2019 年最精彩 AI 论战
  13. 谷歌地图拼接软件_谷歌地图上又有新发现?出现两个长条弧状物体,颜色一白和一黑...
  14. iOS UILabel 设置 行间距 和 字间距 并计算高度
  15. 陈天奇《Introduction to Boosted Trees》PPT 缩略版笔记
  16. leap motion java_leapMotion简介
  17. 不撞南墙不回头----------深度优先搜索
  18. 大厂面试系列(中)—拿到蚂蚁金服社招offer,过来还愿分享面经
  19. 阿里妈妈“广告主套利”风控技术分享
  20. 计算机等级考试备考计划范文,计算机学习计划范文(2)

热门文章

  1. python在财务领域的应用-浅谈财务智能化在实际工作中的运用
  2. python在哪里学比较好-Python学习在哪里比较好?
  3. python下载的文件放在哪里的-python实现文件下载的方法总结
  4. python读取 .mat 文件(matlab文件)
  5. 微信公众平台开发 OAuth2.0网页授权认证
  6. hdu1412 {A} + {B}(TreeSet和Iterator的使用)
  7. 为什么我使用 Linux 开发
  8. wordpress-基础插件,常用函数
  9. day 29 socketsetserver 模块
  10. js中的blob,图片base64URL,file之间的关系