原型规则
- 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了 “null” 除外)
- 所有的引用类型(数组、对象、函数),都有一个 __proto__ 属性,属性值是一个普通的对象
- 所有的函数,都有一个 prototype 属性,属性值也是一个普通的对象
- 所有的引用类型(数组、对象、函数),__proto__ 属性值指向它的构造函数的 “prototype” 属性值
- 当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__(即它的构造函数的 prototype )中寻找
__proto__ 和 prototype 的区别
由上面的规则我们便可知道,__proto__ 是每个对象(数组、对象、函数)都具有的属性,而prototype 是只有函数才有的属性
对象具有属性 __proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法
示例
var obj = {}; obj.a = 10;
var arr = []; arr.a = 10;
function fn() {}; fn.a = 10;
console.log(obj.__proto__ === Object.prototype) //true
console.log(arr.__proto__ === Array.prototype) //true
console.log(fn.__proto__ === Function.prototype) //true示例分析
obj 是构造函数 Object 的实例对象,故实例对象 obj 的隐式原型 __proto__ 指向其构造函数Object 的 prototype 属性,obj 可以访问 Object 原型中定义的属性和方法
arr和fn分析同上
原型链
示例
//构造函数
function Foo(name) {
this.name = name
}
var f = new Foo('xiaoming')分析
如上示例中,f是构造函数Foo的实例对象,故有
f的属性 __proto__ 指向 Foo 的属性 prototype,Foo 是引用类型,具有 __proto__ 属性,这里的属性 __proto__ 指向它的构造函数 Function 的 prototype
Function 的构造函数是它本身,但引用类型的 prototype 值是对象,所以Function.prototype 有 __proto__ 属性,Function.prototype.__proto__ 指向Object.prototype,最后,Object.prototype 的 __proto__ 属性指向null。
Foo.prototype 值的属性是对象,所以也有 Foo.prototype.__proto__ 指向 Object.prototype
所以有如下原型链
