1.__proto__&&prototype
这两个东西我理解了好久,看了好多书的介绍以及别人的博客,这里写写我的理解。百度的面试中就问到了,可是我没回答出来。
看一个例子
function F1(y){
this.y = y ;
}
F1.prototype.x = 10;
F1.prototype.calculate = function(z){
return this.x+this.y+z;
};
var a = new F1(20);
var b = new F1(30);
console.log(a.__proto__ === F1.prototype);//true
console.log(b.__proto__ === F1.prototype);//true
console.log(a.__proto__ === b.__proto__);//true
console.log(F1.prototype.constructor === F1);//true
console.log(F1.prototype.__proto__ === Object.prototype);//true
console.log(F1.__proto__ === Function.prototype);//true
console.log(Function.prototype.__proto__ === Object.prototype);//true
看Firebug中显示的
你们有没有看懂这段代码啊,没事仔细看,直到看不懂为止。
Ok,看不懂了再往下看,我把上面这段代码抽象出一张图来,大家一看就明白了,反正我是看明白了。
有了这张图,就好理解多了是不是。
先补充一句,每个对象都有一个隐藏属性__proto__,当要调用它的属性的时候,先在自身寻找,若没有此属性,则按照__proto__指向的对象去找,若那个对象也没有该属性,再按照那个对象的__proto__所指向的对象继续寻找,直到找不到为止。这就构成了JavaScript的原型链。人体蜈蚣看过没。。。对,原型链大概跟他差不多,那个场面我就不说了。。。
首先,定义一个函数F1
function F1(y){
this.y = y ;
}
当定义一个prototype的时候,会构造一个原形对象,这个原型对象存储于构造这个prototype的函数的原形方法之中.
当程序执行这段代码的时候,会创建出一个F1,并且会产生一个对象F1.prototype,因为F1是调用constructor产生的,F1会存储于prototype的方法之中。然后
F1.prototype.x = 10;
F1.prototype中会添加属性x值为10
F1.prototype.calculate = function(z){
return this.x+this.y+z;
};
与上面类似,prototype中添加属性calculate,值为function
关键点来了
var b = new F1(20);
使用了new关键字,这看似简单的一句话其实过程是:
var b={}; 也就是说,初始化一个对象b。
b.__proto__=F1.prototype;
F1.call(b);也就是说构造b,也可以称之为初始化b。
这样F1就在b的原型链之中了。
顺便说一句,定义F1时,由于F1是对象,所以他的__proto__指向Function.prototype ,Function.prototype的__proto__指向的是Object.prototype,然后他的__proto__是null.
万物都是null创造出来的。难怪佛家说万物皆空,四大皆空。古人就已发现这个亘古不变的道理,阿弥陀佛嘛咪嘛咪哄。。。。