原型
- prototype、[[prototype]]、constructor 三者之间的关系
Javascript 是弱类型语言,它没有类(Class)的概念,但它通过更灵活的原型(Prototype)实现了类的功能。
TIP
ES6 的 Class 只是语法糖,本质上还是 Prototype。
函数和原型
每个函数都有一个 prototype
对象,该对象有一个指向函数本身的 constructor
属性:
function SuperType(){}
SuperType.prototype = {}
prototype
对象中可以添加自定义属性:
function SuperType(){
this.value = 'Hello world'
}
SuperType.prototype.getSuperValue = function(){
return this.value
}
实例和原型
函数的实例对象之所以能访问原型对象是因为实例对象有一个 [[prototype]]
指针指向了原型对象:
var instance = new SuperType()
instance.getSuperValue() // Hello world
浏览器则是通过 __proto__
属性实现了这个指针:
instance.__proto__=== SuperType.prototype // true
Function 和 Object
函数都是 Function
创建出来的,所以所有函数的 [[prototype]]
指针都指向 Function.prototype
,而 Function
本身就是一个函数,所以 Function.__proto__
指向 Function.prototype
,即指向它自己。
对象都是 Object
创建出来的,所以所有的原型对象的 [[prototype]]
指针都指向 Object.prototype
,而 Object
又是一个函数,所以 Object.__proto__
指向 Function.prototype
。
但作为对象最顶端的 Object.prototype.__proto__
指向 null
。
Function.__proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true
原型链
结合上面的结论可得如下关系图:
这种实例和构造函数以及原型对象之间的关系便是原型链。
总结
- 函数都是
Function
创建出来的,即所有函数都是Function
的实例 - 对象都是
Object
创建出来的,即所有对象都是Object
的实例 prototype
链接的是构造函数和原型对象,__proto__
链接的是实例对象和原型对象。
参考文章: