# JavaScript 原型
# proto 和 prototype
__proto__
每个JavaScript对象
一定对应一个原型对象,并从原型对象继承属性和方法。
对象的
__proto__
属性对应的值就是它所对应的构造函数的原型对象
var obj1 = {};
obj1.__proto__ == Object.prototype; //true
obj1.constructor == Object; //true
obj1.prototype //没有这个属性 只有函数才有prototype属性
prototype
prototype属性,不像每个对象都有__proto__
属性来标识自己所继承的原型,只有函数才有prototype属性
为什么只有函数才有prototype属性?
因为当初设计JavaScript的时候使用prototype来模拟类,进而实现继承。
当创建函数时,JavaScript会为这个函数自动添加prototype
属性,值值是一个有 constructor
属性的对象,不是空对象。而一旦你把这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JavaScript就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法(实例通过设置自己的__proto__
指向其构造函数的prototype来实现这种继承)
function foo() {}
foo.prototype
{
constructor: foo()
__proto__: Object
}
foo.__proto__ == Function.prototype; //true
foo.__proto__ == foo.constructor.prototype; //true
foo.constructor == Function; //true
foo.constructor.prototype == Function.prototype; //true
foo.prototype.constructor == foo; //true
foo.__proto__.__proto__ == Object.prototype; //true
# Function and Object
JavaScript是单继承的,Object.prototype是原型链的顶端
Object
本身是构造函数,继承了Function.prototype
;Function
也是对象,继承了Object.prototype
所以:
Object instanceof Function; // true
Function instanceof Object; // true
# OO练习
var a = new Object();
a.param = 123;
function foo(){
get = function(){
console.log(1);
};
return this;
}
foo.get = function(){
console.log(2);
};
foo.prototype.get = function(){
console.log(3);
};
var get = function(){
console.log(4);
};
function get(){
console.log(5);
}
foo.get();
// => 2 实际上是在foo上添加了get方法,foo是函数,同时也是对象,所以可以添加方法
get();
// => 4 函数声明提升,后面在运行时由console.log(4);覆盖
foo().get();
// => 1 实际上是给window上声明了一个get方法
get();
// => 1 被console.log(1);覆盖
new foo.get();
// => 2 使用的是foo.get的属性值
new foo().get();
// => 3 继承原型链上的3
new new foo().get();
// => 3 继承原型链上的3