对prototype和_proto_的理解

340 阅读3分钟

MDN介绍: javascript常被描述为一种基于原型的语言,每个对象拥有一个原型对象,对象以其原型为模板、从原型集成方法和属性。

原型链:原型对象也可能拥有原型,并从中集成方法和属性,一层一层,并以此类推,这种关系常被称为原型链。

在javascript中实现复制是在对象实例和它的构造器之间建立一个链接(它是_proto_属性,是从构造函数的prototype属性派生的),之后通过上溯原型链,在构造器中找到这些属性和方法。

_proto_

是对象独有的属性,它指向的是对象的原型

prototype

1、prototype是构造函数独有的属性,函数.prototype代表的是对象的原型

2、当构造函数执行New操作(也就是创建实例对象时),会把实例对象的_proto_指向构造函数的prototype属性。

function A() {}
let a = new A()
a._proto_ === A.prototype

也就是说,构造函数的prototype和其实例的_proto_是指向同一个地方的。

函数

上面我们提到了构造函数,实质上它也是个函数。

function a1(name, age) {
    console.log(`我是${name}, ${age}岁了`)
}

上述定义函数的,同样的我们可以使用new Function来声明,可以这样写:

const a1 = new Function('name', 'age', ' console.log(`我是${name}, ${age}岁了`)')

在上面说过,构造函数的prototype和其实例的_proto_是指向同一个地方的,所以这里的a1、a2也就是Function构造函数的实例。

对象

创建对象的方法:

1、构造函数创建对象
function Person(name, age) {
    this.name = name
    this.age = age
}
const person1 = new Person('绵绵', 25)

2、字面量创建对象
const person2 = {name: '绵绵', age: 25}

3、new Object创建对象
const person3 = new Object()
person3.name = '绵绵'
person3.age = 25

这里的person2、person3是Object构造函数的实例

console.log(Object.prototype === person2._proto_) // true

Function和Object

从上面两点可以看出,函数是Function构造函数的实例,对象是Object构造函数的实例。

function Object()是Function构造函数的实例

function Function()是Function构造函数的实例

constructor

constructor和prototype是成对存在的

function fn() {}
console.log(fn.prototype) // {constructor: fn}
console.log(fn.prototype.constructor === fn) // true

原型链

先来看看Person.prototype和Function.prototype

  1. Person.prototype 是构造函数Person的原型对象
  2. Function.prototype是构造函数Function的原型对象

原型对象,所以他俩本质都是对象,都是通过new Object()创建的,所以Person.prototype和Function.prototype都是构造函数Function的实例,所以Person.prototype和Function.prototype的_proto_都指向Object.prototype。

那么原型链到底是什么呢?

其实_proto_的路径就叫原型链

从上图看出原型链的终点是Object.prototype,但其实不是的,Object.prototype其实也有_proto_,指向null。

原型继承

先说下定义:原型继承就是实例可以使用构造函数上的prototype中的方法。

functionn Person(name){ // 构造函数
    this.name = name
}
Person.prototype.sayName = function() { // 往原型对象添加方法
    console.log(this.name)
}
const Person = new Person('绵绵') // 实例
// 使用构造函数的prototype中的方法
person.sayName() // 绵绵

instanceOf

使用方法

A instanceof B

作用是:判断B的prototype是否在A的原型链上

funcction Person(name) {
    this.name = name
}
const person = new Person('绵绵')
console.log(Person instance person) // true

资料参考:

juejin.cn/post/700741…