在js中,原型(Prototype) 和 原型链(Prototype Chain) 是理解对象继承和属性查找的机制的核心概念,他们构成了JS基于原型的继承模型
原型
每个函数都有一个prototype属性,它指向一个对象,该对象就是该函数创建的实例的原型- 原型对象是其他对象的“模板”,用于共享属性和方法
function a(name) {this.name = name}
var b = new a() // b是a的实例
a.prototype // => {} 每个函数都有一个prototype属性,它指向一个对象
b.__proto__ === a.prototype // => true 该对象(a.prototype)就是该函数(a())创建的实例(b)的原型(__proto__),都指向了同一个原型对象(prototype)
// .prototype 构造函数的原型
// .__proto__ 实例对象的原型
原型链
-
多个对象通过原型相互链接形成的链条关系
-
当访问一个属性(或方法)时,如果当前对象上没有该属性,则会沿着原型一直向上查找,一直找到原型链的顶端null为止
-
链式查找示例
function Person(name) {this.name = name} var alice = new Person() alice.toString() // 调用的是Object.prototype.toString() 输出 => '[object Object]'-
查找路径:
- alice自身 -> Person.prototype -> Object.prototype -> null
-
可以修改为
function Person(name) {this.name = name} Person.prototype.toString = function () {console.log(123)} var alice = new Person() alice.toString() // 调用的是Person.prototype.toString() 输出 => 123- 手动修改原型链
// 通过`Object.create()`拓展原型链 const parent = { familyName: "Smith" }; // Object.create(...): 创建返回一个新对象,并把新对象中的[[prototype]]关联到指定对象上 const child = Object.create(parent); console.log(child) // {} console.log(child.familyName); // 输出: Smith parent.hasOwnProperty('familyName') // true child.hasOwnProperty('familyName') // false -
-
原型链的重要性
- 原型链是JS实现
继承和属性共享的核心机制
- 原型链是JS实现
构造函数
- function a() {console.log(1)} 和 fcuntion b(name) {this.name = name},a 和 b 是否都是构造函数?
- 构造函数不是看它是怎么定义,而是看它是怎么使用,当使用
new关键词时,则该函数就可以作为构造函数,当直接使用时,则是一个普通函数 - 实际开发中,构造函数
首字母通常大写,以便区分
- 构造函数不是看它是怎么定义,而是看它是怎么使用,当使用
function Foo() {}
var f = new Foo()
f.constructor === Foo // true constructor指向其实例的构造函数本身
f.constructor.prototype === Foo.prototype // true