资讯专栏INFORMATION COLUMN

你真的明白javascript中的原型和原型链了吗

Harpsichord1207 / 3263人阅读

摘要:补充的知识这个是原型中的自带属性,指向构造函数这个属性其实是浏览器实现的,不是标准的访问原型的方式中规定的正式方法是以上知识,最终的图如下思考题在文章开头我们说过函数也是对象,既然是对象就有原型,那的原型指向谁呢是吗

文章开头说的话

首先你必须明白(或者记住)的JavaScript常识:

在JavaScript中每个函数都有一个prototype属性

在JavaScript中每个对象都有一个__proto__属性

在JavaScript中函数是一等公民,即函数也是对象

prototype和__proto__

prototype到底是个啥呢?下面看下这段代码,我们慢慢来

// Animal是个构造函数,所以有prototype属性
function Animal(){}
// 在prototype上定义eat方法
Animal.prototype.eat = function(food){
  console.log("it is eating " + food);  
}
// 构造函数实例化a1
const a1 = new Animal();
// 构造函数实例化a2
const a2 = new Animal();
// 调用实例的方法
a1.eat("food");
a2.eat("food");

从上面的代码中,我们可以看到:

函数的prototype指向一个对象

函数实例化后的对象可以获取prototype指向对象的方法(和属性)

那他们之前的关系是怎么样的呢?

从图中我们可以看到:

Animal的prototype指向一个对象

Animal的实例通过__proto__关联到Animal的prototype指向的对象

用官方术语说,就是:

函数的prototype所指向的对象就是该函数创建的实例的原型(即:a2和a2的原型是Animal.prototype)

那么问题来了,什么是原型呢?
在JavaScript中,每个对象(null除外)在创建的时候都会与之关联另外一个对象,对象和原型之间通过__proto__进行关联

原型的作用

在上面的代码中,我们可以看到实例对象中并没有eat方法,但是每个实例对象都可以调用eat方法,那中间的过程是怎样的呢?

当我们调用实例对象(a1和a2)的方法(eat)的时候,如果找到则直接调用实例对象的方法或者属性;如果找不到,就会查找与之关联的原型上是否有这个方法,如果这个原型没有,就会继续向上查找该原型的原型(原型的原型后面探讨)

原型的原型

在上面我们提到了如果在原型上找不到相应的属性或者方法,就会在原型的原型上查找,那么什么是原型的原型呢?

首先在文章开头我们说每个对象都有原型,而原型也是对象,所以原型也是有原型的(听起来有点绕)

那之前代码的Animal.prototype的原型指向哪里呢(即Animal.prototype.__proto__)指向谁呢?这里Animal.prototype是JavaScript内置构造函数Object生成的呢,那是不是应该指向Object.prototype呢?答案是是的。

那Object.prototype也是对象,它的原型呢?Object.prototype.__proto__指向哪个对象呢?答案是:null;即:

Object.prototype.__proto__ === null // true
// 表示如果查找属性的时候到Object.prototype时还是没有就停止,没有了

最后画张图:

原型链

注意到上图中的蓝色线条部分了吗,这就是大名鼎鼎的原型链。

补充的知识

constructor: 这个是原型中的自带属性,指向构造函数

__proto__: 这个属性其实是浏览器实现的,不是标准的访问原型的方式;ES5中规定的正式方法是:Object.getPrototypeOffang"fa

Object.getPrototypeOf(a1) === Animal.prototype // true

以上知识,最终的图如下:

思考题:

在文章开头我们说过函数也是对象,既然是对象就有原型,那Animal的原型指向谁呢?

Function.prototype === Function.__proto__ 是true吗?

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

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

相关文章

  • 真的明白 new 了吗

    摘要:如果构造函数有返回值呢一般情况下构造函数没有返回值,但是我们依旧可以得到该对象的实例如果构造函数有返回值,凭直觉来说情况应该会不一样。欢迎光临小弟博客我的博客原文你真的弄明白了吗参考再谈面向对象编程的实例化与继承请停止使用关键字 好久没有写点东西了,总觉得自己应该写点牛逼的,却又不知道如何下笔。既然如此,还是回归最基本的吧,今天就来说一说这个new。关于javascript的new关键...

    tolerious 评论0 收藏0
  • 彻底搞懂JavaScript中的继承

    摘要:这正是我们想要的太棒了毫不意外的,这种继承的方式被称为构造函数继承,在中是一种关键的实现的继承方法,相信你已经很好的掌握了。 你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- 继承就和原型链这一概念息息相关。甚至可以说,所谓的原型链就是一条继承链。有些困惑了吗?接着看下去吧。 一、构造函数,原型属性与实例对象 要搞清楚如何在JavaScript中实现继承,...

    _ivan 评论0 收藏0
  • javascript对象详解:__proto__prototype的区别联系

    摘要:当这步完成,这个对象就与构造函数再无联系,这个时候即使构造函数再加任何成员,都不再影响已经实例化的对象了。此时,对象具有了和属性,同时具有了构造函数的原型对象的所有成员,当然,此时该原型对象是没有成员的。 前言 本篇文章用来记录下最近研究对象的一些心得,做一个记录与总结,以加深自己的印象,同时,希望也能给正在学习中的你一点启发。本文适合有一定JavaScript基础的童鞋阅读。原文戳这...

    chavesgu 评论0 收藏0
  • 如何优雅的理解ECMAScript中的对象

    摘要:标准对象,语义由本规范定义的对象。这意味着虽然有,本质上依然是构造函数,并不能像那样表演多继承嵌套类等高难度动作。不过这里的并不是我们所说的数据类型,而是对象构造函数。 序 ECMAScript is an object-oriented programming language for performing computations and manipulating computat...

    why_rookie 评论0 收藏0

发表评论

0条评论

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