@(JavaScript原型)
JavaScript中最晦涩难懂的恐怕就是原型了。故以此笔记原本记录原型的学习过程,往后忘了可来温习。javascript
null
——Object
&Function
——prototype
&constructor
java
__proto__
在JavaScript中,每一个对象都拥有一个原型对象,而指向该原型对象的内部指针则是
__proto__
,经过它能够从中继承原型对象的属性。从对象的__proto__
能够访问到它所继承的原型对象。函数
var a = new Array(); a.__proto__ === Array.prototype //true a.__proto__.__proto__ === Object.prototype //true a.__proto__.__proto__.__proto__ === null //true
如图,JavaScript中的对象,追根溯源都是来自一个
null
对象。
除了使用.__proto__
方式访问对象的原型,还能够经过Object.getPrototypeOf
方法来获取对象的原型,以及经过Object.setPrototypeOf
方法来重写对象的原型。post
prototype
函数既是函数又是对象,函数的原型指向
Function.prototype
,函数实例除了有__proto__
属性以外,还有prototype
属性。经过该函数构造的新的实例对象,其原型指针__pro__
会指向该函数的prototype
属性。而函数的prototype
属性,自己是一个由Object
构造的实例对象。prototype
属性很特殊,它还有一个隐式的constructor
,指向了构造函数自己。学习
var Foo = function() {}; Foo.__proto__ === Function.prototype //true var a = new Foo(); a.__proto__ === Foo.prototype //true Foo.prototype.__proto__ === Object.prototype //true Foo.prototype.constructor === Foo //true a.constructor === Foo //true a.constructor === Foo.prototype.constructor //true
a.constructor
属性并不属于a
而是读取的a.__proto__.constructor
,因此上图用虚线表示a.constructor
,方便理解。
即(a.hasOwnProperty("constructor")===false
)prototype
原型链做为实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另外一个引用类型的属性和方法。
每一个构造函数都有一个原型对象(prototype
),原型对象都包含一个指向构造函数的指针(constructor
),而实例都包含一个指向原型对象的内部指针。
原型链的做用在于,当读取对象的某个属性时,JavaScript引擎先寻找对象自己的属性,若是找不到,就到它的原型去找,若是仍是找不到,就到原型的原型去找。以此类推,若是直到最顶层的Object.prototype
仍是找不到,则返回undefined
。指针
instanceof
运算符返回一个布尔值,表示一个对象是否由某个构造函数建立。Object.isPrototypeOf()
只要某个对象处于原型链上,isPrototypeOf
都 返回true
var Bar = function() {}; var b = new Bar(); b instanceof Bar //true Bar.prototype.isPrototypeOf(b) //true Object.prototype.isPrototypeOf(Bar) //true
注意:实例
b
的原型是Bar.prototype
而不是Bar
。code
Function.prototype.__proto__ === Object.prototype
Object.prototype.constructor.__proto__ === Function.prototype
即说明Function.prototype
是一个Object
实例,而没有Function
,Object
也不能建立实例。对象
以下图:
blog
其中,Op
表明Object.prototype
,Fp
表明Function.prototype
。
以上,参考@Jerrc
---恢复内容结束---
@(JavaScript原型)