# 构造函数 - 原型 - 原型链

# 构造函数

# 什么是构造函数

constructor返回创建实例对象时构造函数的引用

function Parent(age) {
    this.age = age
}

const instance = new Parent(50)

instance.constructor === Parent // true
insatnce.constructor === Object //false
1
2
3
4
5
6
7
8

构造函数和普通函数的区别在于是否使用 new 关键字进行生成

# constructor只读吗

对于引用类型来说 constructor 是可以修改的,比如原型继承中的 constructor 赋值修正

function Foo() {
    this.value = 42
}
Foo.prototype = {
    method: function() {}
}

function Bar() {}

Bar.prototype = new Foo()
Bar.prototype.constructor === Object // true

// 修正
Bar.prototype.constructor = Bar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

对于基本类型来说constructor是只读的,并且 undefined 和 null 是没有 constructor 属性的

# 原型

# prototype

JS 是基于原型设计的语言,这和 Java 等基于类的语言不一样

原型模式本质是一种设计方法,通过“复制“一个已经存在的实例来返回新的实例,而不是新建实例,多用于创建复杂的或者耗时的实例

构造函数有一个指向原型的指针,即 Parent.prototype ,原型也有一个指向构造函数的指针即 Parent.prototype.constructor ,实质上是一个循环引用

# proto

该特性已从 Web 标准中废弃,请尽量不要使用该特性

__proto__ 是每个实例上都有的属性,prototype 是构造函数的属性,这两者不一样,但是两者指向同一个对象

推荐使用 Object.getPrototypeOf() 替代

# 原型链

每个实例对象( object )都有一个私有属性(称之为 __proto__ )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( __proto__) ,层层向上直到一个对象的原型对象为 null

function Parent(age) {
    this.age = age
}
let p = new Parent(10)

p.__proto__ === Parent.prototype // true
p.__proto__ === Object.prototype // true
p.__proto__.__proto__ === null // true
1
2
3
4
5
6
7
8