资讯专栏INFORMATION COLUMN

JavaScript进阶 - 1. 原型和原型链的概念

elisa.yang / 1189人阅读

摘要:对应的关系图如下讲解了构造函数和原型对象之间的关系,那么实例对象和原型对象之间的关系又是怎么样的呢下面讲解。原型对象的指向的是构造函数和本身没有属性,但是其原型对象有该属性,因此也能获取到构造函数。

JavaScript进阶 - 1. 原型和原型链的概念

我们好多经常会被问道JavaScript原型和原型链的概念,还有关于继承,new操作符相关的概念。本文就专门整理了原型和原型链的概念,关于对象继承我们后边进行介绍。本文包含对应的示例代码和脑图。如有奇异,欢迎指正!

目录讲解

1. 构造函数创建对象

2. 相关的名词介绍

2.1 prototype

2.2 _proto_

2.3 constructor

3. 实例和原型 原型和原型

4. 原型链是怎么产生的(附有相关的关系图说明)

1. 构造函数创建对象

我们先使用构造函数的方式声明一个对象:

function Person() {}
let person = new Person()
person.name = "小红"
console.log(person.name) // 小红

在上面的代码中。Person是构造函数, person是通过new方式创建的实例对象。
现在开始进入一个环节

2. 相关的名词介绍

prototype,constructor,__proto__是我们经常见到的几个概念,但是他们之间的关系具体是什么样的呢,让我们逐步开始了解。

2.1 prototype

每个函数都有 prototype 属性,除了 Function.prototype.bind(),该属性指向原型, prototype: 指向实例对象的原型对象

function Person() {}
Person.prototype.name = "小红"
let person = new Person()
console.log(person.name) // 小红

Person这个函数有声明prototype属性,那么这个值指向的到底是哪儿,是原型对象吗?

其实prototype指向的是,调用当前构造函数创建实例对象的原型,也就是person的原型。

那么原型到底是什么呢?其实原型可以理解为,一个JavaScript对象(null除外)在创建的时候会关联另外一个对象,这个被关联的对象就是我们说的原型对象,实例对象会在创建的时候,从原型对象继承一些属性或者方法。

对应的关系图如下:

2.2 proto

prototype讲解了构造函数和原型对象之间的关系,那么实例对象和原型对象之间的关系又是怎么样的呢?下面讲解。每个JavaScript对象(null除外),都会有个__proto__的属性,这个属性指向的就是原型对象

function Person() {}
let person = new Person()
console.log(person.__proto__ === Person.prototype) // true
// ES5  通过实例对象获取原型对象的方法
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

由此我们上面的管理系图谱可以补充为:

2.3 constructor

上面讲解了原型对象和构造函数,实例对象之间的关系,那么反过来获取原型对象和实例对象的构造函数是不是能获取到呢??constructor就能做到这一点。constructor: 指向该原型对象对应的构造函数

function Person() {}
let person = new Person()
// 原型对象的构造函数
console.log(Person.prototype.constructor === Person) // true
// 实例对象的构造函数
console.log(person.constructor === Person)  // true
// 实例对象本身是否含有constructor属性
console.log(person.hasOwnProperty("constructor"))  // false

注意:
person.constructor 中实际上是没有constructor属性的,这是从person的原型中获取到的constructor属性才有了  person.constructor === Person。通过

关系图可以补充为:

3. 实例和原型 原型和原型 3.1 实例和原型

当我们读取一个对象的属性是,如果实例对象中能找到,就会返回实例对象对应的value,如果没有找到,就会站到实例对象的原型对象中,查看有无此值,有则返回,没有的话,继续查找原型的原型对象上有无此值。一直会查到顶层为止。

function Person() {}
Person.prototype.name = "小红"

let person1 = new Person()
let person2 = new Person()

person2.name = "小明"
console.log(person1.name) //小红
console.log(person2.name) //小明

那么原型的原型执行的是什么呢?

3.2 原型和原型

实际上,原型的原型也是一个实例对象,是通过Object的构造函数生成的,因此,原型的原型也能通过__proto__获取其对应的原型对象的属性。

function Person() {}
Object.prototype.name = "sunny"

let person1 = new Person()
let person2 = new Person()

console.log(person1.name) //sunny
console.log(person2.name) //sunny

对应的关系图如下:

4. 原型链是怎么产生的(附有相关的关系图说明)
console.log(Object.prototype.__proto__ === null) // true

Object.prototype的原型为null, null代表的意思是没有对象,为空。换句话的意思就是说,没有原型对象了,这也就是查找的顶层对象了。

整个的关系图我们梳理为:

关系图中,红色的线其实就是我们平时说的原型链

扩展内容

我们知道函数其实也是一个对象,任何函数都能看成是Function()通过new实例化后的结果。因此,如果把Person和Object当做是实例对象的话,他们的原型指向的是构造函数Function()的实例对象Function.prototype。

console.log(Person.__proto__ === Function.prototype) //true
console.log(Object.__proto__ === Function.prototype) //true

原型对象Function.prototype的constructor指向的是构造函数Function,Person和Object本身没有constructor属性,但是其原型对象有该属性,因此也能获取到构造函数。

console.log(Function.prototype.constructor === Function) // true
console.log(Person.constructor === Function) //true
console.log(Person.hasOwnProperty("constructor")) //false
console.log(Object.constructor === Function) //true
console.log(Object.hasOwnProperty("constructor")) //false

所有的函数对象都可以看成是Function通过new之后生成的实例对象,那么Function可以看成是自己调用自己实例化的结果产生的。因此有Function的实例对象指向Function.prototype

console.log(Function.prototype === Function.__proto__) // true
console.log(Function.prototype === Function.prototype) //true

如果此时的Function.prototype作为实例,那么他自己的实例对象执行的又是谁呢?所有的对象都可以看作是Object实例化的结果。所以,Function.prototype的原型对象是Object.prototype,其原型函数是Object()。

console.log(Function.prototype.__proto__ === Object.prototype);  //true

把这些全部总结完,之后我们的关系图,就变成了下面这个样子:

参考文章
JavaScript深入之从原型到原型链

一张图理解JS的原型(prototype、_proto_、constructor的三角关系)

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

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

相关文章

  • 【前端基础进阶】JS原型原型链、对象详解

    摘要:二构造函数我们先复习一下构造函数的知识上面的例子中和都是的实例。这两个实例都有一个构造函数属性,该属性是一个指针指向。原型链其中是对象的实例。 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的。分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象。下面举例说明 var o1 = {}; var o2 =new Objec...

    explorer_ddf 评论0 收藏0
  • JS进阶(1) —— 人人都能懂的构造函数

    摘要:构造函数的执行过程先说一点基本概念。只有当一个函数以关键字来调用的时候,我们才能说它是一个构造函数。构造函数的返回值构造函数执行过程的最后一步是默认返回。 showImg(https://segmentfault.com/img/bV55lY?w=500&h=312); 大家都知道原型和原型链是 JavaScript 中最经典的问题之一,而构造函数又是原型和原型链的基础,所以先了解清楚...

    Blackjun 评论0 收藏0
  • 前端基础进阶(九):详解面向对象、构造函数、原型原型

    摘要:我们通过一个简单的例子与图示,来了解构造函数,实例与原型三者之间的关系。而原型对象的指向构造函数。于是根据构造函数与原型的特性,我们就可以将在构造函数中,通过声明的属性与方法称为私有变量与方法,它们被当前被某一个实例对象所独有。 showImg(https://segmentfault.com/img/remote/1460000008593382); 如果要我总结一下学习前端以来我遇...

    Tony_Zby 评论0 收藏0
  • JS基础-原型原型链真的不能一知半解

    摘要:原型链和对象的原型是对象实例和它的构造函数之间建立的链接,它的值是构造函数的。对象的原型根据上文提到的构造调用函数的时候会创建一个新对象,自动将的原型指向构造函数的对象。 showImg(https://segmentfault.com/img/remote/1460000020185197); JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清...

    changfeng1050 评论0 收藏0
  • 【连载】前端个人文章整理-从基础到入门

    摘要:个人前端文章整理从最开始萌生写文章的想法,到着手开始写,再到现在已经一年的时间了,由于工作比较忙,更新缓慢,后面还是会继更新,现将已经写好的文章整理一个目录,方便更多的小伙伴去学习。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 个人前端文章整理 从最开始萌生写文章的想法,到着手...

    madthumb 评论0 收藏0

发表评论

0条评论

elisa.yang

|高级讲师

TA的文章

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