原型与原型链
- 函数的
prototype
属性- 每个函数都有一个
prototype
属性,它默认指向一个Object
空对象(原型对象) - 原型对象中有一个属性
constructor
,它指向函数对象
- 每个函数都有一个
- 给原型对象添加属性
- 作用:函数的所有实例对象自动拥有原型中的属性(方法)
js
console.log(Date.prototype.constructor === Date) // 原型对象中有一个属性 `constructor`,它指向函数对象
显示原型与隐式原型
- 每个函数
function
都有一个prototype
,即显示原型 - 每个实例对象都一个
__proto__
,即隐式原型 - 对象的隐式原型的值为其对应构造函数的显示原型的值
- 总结
- 函数的
prototype
属性:在定义函数时自动添加,默认值为一个空对象 - 对象的
__proto__
的属性: 创建对象的时候自动添加,默认值为构造函数的prototype
属性值 - 能直接操作显示原型,不可直接操作隐式原型(ES6之前)
- 函数的
js
// 定义构造函数
function Fn() {} // 内部语句:this.prototype = {}
// 1. 每个函数function都有一个prototype,即显示原型属性,默认指向一个空`Object`对象
console.log(Fn.prototype)
// 2. 每个实例对象都一个__proto__,即隐式原型
// 创建实例对象
var fn = new Fn() // 内部语句:this.__proto__ = Fn.prototype
console.log(fn.__proto__)
// 3. 对象的隐式原型的值为其对应构造函数的显示原型的值
console.log(Fn.prototype === fn.__proto__) // true
// 给原型添加方法
Fn.prototype.test = function() {}
// 通过实例对象调用原型方法
fn.test()
原型链
原型链
- 访问一个对象的属性时
- 先在自身属性中查找,找到返回
- 如果没有,再沿着
__proto__
这条链向上查找,找到返回 - 如果最终没有找到,返回
undefined
- 别名:隐式原型链
- 作用:查找对象的属性(方法)
- 访问一个对象的属性时
构造函数/原型/实体对象的关系
函数的显示原型指向的对象:默认一个空的
Object
实例对象(但Object
不满足)jsconsole.log(Fn.prototype instanceof Object) // true console.log(Object.prototype instanceof Object) // false console.log(Function.prototype instanceof Object) // true
所有函数都是
Function
的实例(包含Function)jsconsole.log(Function.__proto__ === Function.prototype) // true
Object
的原型对象是原型链的尽头jsconsole.log(Object.prototype.__proto__) // null
原型链属性
读取对象的属性值时:会自动到原型链中查找
设置对象的属性值时:不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值
方法一般定义在原型中,属性一般通过构造函数定义在对象本身上
jsfunction Fn() {} Fn.prototype.a = 'mondo' var fn1 = new Fn() console.log(fn1.a, fn1) // mondo var fn2 = new Fn() fn2.a = 'imondo' console.log(fn1.a, fn2.a, fn2) // mondo imondo function A() {} A.prototype.n = 1 var b = new A() A.prototype = { n: 1, m: 2 } var c = new A() console.log(b.n, b.m, c.n, c.m) // 1, undefined, 1, 2
instanceof判断
instanceof
是如何判断- 表达式:
A instanceof B
- 如果 B 函数的显示原型对象在 A 对象的原型链上, 返回 true,否则返回 false
- 表达式:
Function
是通过new
自己产生的实例jsfunction Foo() {} var f1 = new Foo() console.log(f1 instanceof Foo) // true console.log(f1 instanceof Object) // true console.log(Object instanceof Function) // true console.log(Object instanceof Object) // true console.log(Function instanceof Function) // true console.log(Function instanceof Object) // true console.log(Object instanceof Foo) // false