资讯专栏INFORMATION COLUMN

原型链一:原型与原型链

MudOnTire / 3229人阅读

摘要:说白了,原型就是构造函数用来构造新实例的模板对象。什么是原型链先回答什么是原型。例如这个原型的原型就是这个构造函数的,既这个原型对象。这些原型对象通过像链子一样连起来,就叫做原型链。

原型链初步学习

这篇博客只是我初步理解原型链的一个个人学习笔记,写的比较粗略,且有的地方可能理解错误.

更多更专业的关于原型链的解释请看JavaScript深入之从原型到原型链和阮一峰的博客:Javascript继承机制的设计思想

JS标准库里几个构造函数之间的关系


每个对象都有toString()valueOf()函数,如果每个对象里都存这样的相同的函数,那会浪费内存.
问题解决方法:原型链

toString()valueOf()等函数多带带存放在一个对象里,原来对象里的toString()valueOf()只存地址,指向这个地址

当声明对象是,出来自己定义的属性,还有一个隐藏的属性
__proto__ 里面存的是toString()valueOf()等的地址
他的值就是公用属性的值


共有的属性和方法

在执行o1.toString()是发生的事:
首先看o1
是不是真正的对象,如果不是,就包装成临时对象,用完再回收垃圾,然后进入对象,看他有没有toString方法,如果有特有的toString(),就用,如果没有,就进入__proto__属性去找toString()方法.


说明所有的toString()都是同一个地址

__proto__进阶

如果这个对象不是普通对象拥有特有的方法,会一层一层去找

代码:

第一层的toString()Number()特有的,可以转换成16进制
toString(16),第二层里面的的toString()是所有对象都有的公共属性.比如找valueOf()如果在第一层里 __proto__ 找不到,就去第二层找.

数字对象普通对象
结构:

原型链

所有的共有属性,,如果没有东西引用他,就会被垃圾回收,那么谁在引用他呢?
答案是 prototype ,prototype的意思是 原型.
所有函数都有protoype属性,包括构造函数.即String(),Number(),Boolean(),Object()protoype
在最开始JS初始化的时候,函数的protoype属性会加载到内存当中

原型===共有属性
Object.prototype意思还是Object的共有属性


Object是构造函数(JS里函数也是一种对象,也可以有方法,可以 有属性)
函数名字加()就是执行.


Number的共有属性

共有属性的共有属性

其他String,Boolean原型也是一样

new做的事情,一创造一个哈希,二绑定原型(共有属性),即把__proto__指向该有的共有属性,也就是原型

__proto__prototype的关系

[__proto__指向prototype],

在无代码情况下
window里面有Number属性(函数也是对象,也可以有属性)
实际上为
Number:function Number(){}这个

无代码的时候,即为下面这样,浏览器已经将其初始化好了.

可以看到prototype用来指向这些共有属性的,不然这些共有属性就被垃圾回收了,所以要用一个线来牵引着.
如图

写了代码之后

所以:

prototype是浏览器开始就准备好了的,用来防止共有属性被垃圾回收的,

__proto__是在开始写代码的时候用来引用共有函数的.

String.prototypeString的公用属性的引用,是JS在初始化的时候就已经存在的,用他是因为如果不用他,那么公用属性就跑了,被垃圾回收了

"s".__proto__String的公用属性的引用,是在声明新对象的时候存在的,有他是因为我要用他,用公用属性

共同点就是都是公共属性的引用.

var o1 = {};

o1.__proto__ ===  Object.prototype//true
Number.prototype.__proto__===Object.prototype//true
var s1 = new String("s1");

s1.__proto__ === String.prototype//true

String.prototype.__proto__ ===Object.prototype//true

function DOG(name){
    this.name = name;
}
DOG.prototype.__proto__ === Object.prototype//true
对象与构造函数


形式

总结的式子


只有函数才能有prototype
两个属性对比:
共同点:存的地址相同,都指向同一个对象
不同点:一个是对象的属性,一个是函数的属性
面试题:
1
"1".__proto__
"1"会创建一个临时String对象,然后指向String.prototype

2
函数.prototype 是一个对象,那么

var obj = 函数.prototype;
obj.__proto__ === Object.prototype;//true
函数.prototype.__proto__ === Object.prototype;//true

成立(可以看上图无代码的时候)

Number.prototype.__proto__ === Object.prototype
//true
String.prototype.__proto__ === Object.prototype
//true
Boolean.prototype.__proto__ === Object.prototype
//true

成立

原型链面试:

怎么回答

JS 原型是什么?

举例

var a = [1,2,3]

只有0、1、2、length 4 个key

为什么可以 a.push(4)push 是哪来的?

a.__proto__ === Array.prototype(a是实例数组对象,Array是构造函数)

push函数 就是沿着 a.__proto__ 找到的,也就是 Array.prototype.push

Array.prototype 还有很多方法,如 joinpopslicespliceconcat

Array.prototype 就是 a 的原型(proto)

聚完例子后用new对象举例,说给面试官听:
比若说

我们新创建一个构造函数

function Person() {}

然后根据构造函数构造一个新对象

 var person1 = new Person();

每个函数都有一个 prototype 属性,这个构造函数prototype 属性指向了一个对象,这个对象调用该构造函数而创建的实例原型

当我们给Personprototypename属性赋值为"Kevin"

Person.prototype.name = "Kevin";
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin

每一个新的实例对象对象都会从原型"继承"属性,实例对象拥有该原型的所有属性。

说白了,原型就是 构造函数 用来 构造 新实例 的 模板对象。

这就是原型。

开始解释原型链
那么我们该怎么表示实例实例原型,也就是 person1 和 Person.prototype 之间的关系呢,这时候我们就要讲到第二个属性__proto__

什么是原型链?

先回答什么是原型。在上面,然后继续从__proto__开始往下说。

说:

JavaScript对象除了 null 都具有的一个属性,叫__proto__,这个属性会指向该对象的原型对象。

当读取实例的属性时,如果找不到,就会通过__proto__查找原型中的属性,如果还查不到,就去找原型原型

例如Person.prototype这个原型的原型就是Object这个构造函数的prototype,既Object.prototype这个原型对象。然后,Person.prototype.__proto__就指向Object.prototype这个原型。然后Object.prototype原型是null

这些原型对象通过__proto__像链子一样连起来,就叫做原型链。

然后给面试官画:

链子上都画上__proto__
person1----->Person.prototype----->Object.prototype----->null

Array.prototype----->Object.prototype----->null

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94834.html

相关文章

  • 关于javascript的原型原型,看我就够了(二)

    摘要:原文链接关于的原型和原型链,看我就够了一参考链接闯关记之原型及原型链之原型与原型链一篇文章带你理解原型和原型链彻底理解原型链一的默认指向图解和的三角关系原型和原型链三张图搞懂的原型对象与原型链 温故 创建对象的三种方式 通过对象直接量 通过new创建对象 通过Object.create() js中对象分为两种 函数对象 普通对象 仔细观察如下代码 function Foo(na...

    eccozhou 评论0 收藏0
  • 继承原型

    摘要:既然构造函数有属于自己的原型对象,那么我们应该能让另一个构造函数来继承他的原型对象咯我们在构造函数内部执行了函数并改变了函数内部的指向其实这个指向的是实例化之后的对象。 我们在讨(mian)论(shi)JavaScript这门语言时,总是绕不过的一个话题就是继承与原型链。那么继承与原型链到底是什么呢? 我很喜欢的一个聊天模式是:我不能说XX是什么,我只能说XX像什么。也就是说我不直接跟...

    My_Oh_My 评论0 收藏0
  • JS之继承(ES5 & ES6)

    摘要:继承可以使得子类具有父类别的各种属性和方法。继承是类与类之间的关系。继承的实质就是两次的原型搜索,像是实例属性而不是继承,才是继承。更多用法见继承。 前言 面试中最常会问到的问题:什么是继承?如何分别用 ES5 和 ES6 实现?想要学习继承,必须先学好原型与原型链,如果此部分还不清楚,请先学习此部分再来阅读本文,可参考我的文章JS之原型与原型链或浏览其他相关的学习网站。 定义 继承...

    antyiwei 评论0 收藏0
  • JavaScript进阶 - 1. 原型原型的概念

    摘要:对应的关系图如下讲解了构造函数和原型对象之间的关系,那么实例对象和原型对象之间的关系又是怎么样的呢下面讲解。原型对象的指向的是构造函数和本身没有属性,但是其原型对象有该属性,因此也能获取到构造函数。 JavaScript进阶 - 1. 原型和原型链的概念 我们好多经常会被问道JavaScript原型和原型链的概念,还有关于继承,new操作符相关的概念。本文就专门整理了原型和原型链的概念...

    elisa.yang 评论0 收藏0
  • 深度解析原型中的各个难点

    摘要:的过程新生成了一个对象链接到原型绑定返回新对象在调用的过程中会发生以上四件事情,我们也可以试着来自己实现一个创建一个空的对象获得构造函数链接到原型绑定,执行构造函数确保出来的是个对象对于实例对象来说,都是通过产生的,无论是还是。 showImg(https://segmentfault.com/img/bVbhZun?w=488&h=590); prototype 首先来介绍下 pro...

    zhangke3016 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<