1. 原型 / 构造函数 / 实例
- 原型
(prototype)
: 一个简单的对象,用于实现对象的 属性继承。原型对象即为当前实例对象的父对象。在 Firefox 和 Chrome 中,每个JavaScript
对象中都包含一个__proto__
(非标准)的属性指向它爹(该对象的原型),可通过obj.__proto__
进行访问。
所有函数都有一个特别的属性:prototype
: 显式原型属性
所有实例对象都有一个特别的属性:__proto__
: 隐式原型属性
显式原型与隐式原型的关系 - 函数的
prototype
: 定义函数时被自动赋值, 默认值是一个空Object对象, 即为原型对象 - 实例对象的
__proto__
: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype
值 - 对象的隐式原型的值为其对应构造函数的显式原型的值
构造函数: 可以通过
new
来 新建一个对象 的函数。实例: 通过构造函数和
new
创建出来的对象,便是实例。-
三者关系: 实例通过
__proto__
指向原型,原型通过constructor
指向构造函数。
以Object
为例,我们常用的Object
便是一个构造函数,因此我们可以通过它构建实例。
// 实例
const o1 = new Object()
则此时, 实例为o1
, 构造函数为Object
,我们知道,构造函数拥有一个prototype
的属性指向原型,因此原型为:
// 原型
const prototype = Object.prototype
这里我们可以来看出三者的关系:
实例.__proto__ === 原型
原型.constructor === 构造函数
构造函数.prototype === 原型
2.原型链:
别名: 隐式原型链
原型链是由原型对象组成,所有的实例对象都有__proto__
属性,指向了创建该对象的构造函数的原型,__proto__
将对象连接起来组成了一个链的结构---->原型链。是一个用来实现继承和共享属性的有限的对象链。属性查找机制: 当查找对象的属性时,先在自身属性中查找,找到返回,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象
Object.prototype
,如还是没找到,则输出undefined
;属性修改机制: 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改原型的属性时,则可以用:
b.prototype.x = 2
;但是这样会造成所有继承于该对象的实例的属性发生改变。原型继承:构造函数的实例对象自动拥有构造函数原型对象的属性(方法),利用的就是原型链。
方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上。
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function (name) {
this.name = name
}
-
Object和Function
函数的显示原型指向的对象默认是空Object
实例对象(但Object
不满足)
console.log(Fn.prototype instanceof Object) // true
console.log(Object.prototype instanceof Object) // false
console.log(Function.prototype instanceof Object) // true
所有函数都是Function
的实例(包含Function
)
console.log(Function.__proto__===Function.prototype)
Object
的原型对象是原型链尽头
console.log(Object.prototype.__proto__) // null
3.探索instanceof
- instanceof是如何判断的?
- 表达式:
A instanceof B
- 如果B函数的显式原型对象在A对象的原型链上, 返回
true
, 否则返回false
- Function是通过new自己产生的实例
console.log(Object instanceof Function);
console.log(Object instanceof Object);
console.log(Function instanceof Function);
console.log(Function instanceof Object);
function Foo() {}
console.log(Object instanceof Foo);