foo.getName

foo.getName
文章图片
timg.jpg
function foo(){ //代码1
getName=function(){
console.log(1);
};
return this;
};
foo.getName=function () { //代码2
console.log(2);
};
foo.prototype.getName=function(){ //代码3
console.log(3);
};
var getName=function(){ //代码4
console.log(4);
};
function getName(){ //代码5
console.log(5);
};
foo.getName(); //标号1,输出2
getName(); //标号2,输出4
foo().getName(); //标号3,输出1
getName(); //标号4,输出1
new foo.getName(); //标号5,输出2
new foo().getName(); //标号6,输出3
new new foo().getName(); //标号7,输出3

刚看到这样的东西的时候,我也迷惑了好久,细想也就是赋值、作用域、原型链的事。
首先代码1中的getName,代码4、5的getName的作用域都是window
1.标号1处的foo.getName(); 这个毫无疑问作用域直接找到,输出2;
2.标号2处的getName(); 主要在于代码4和代码5,在浏览器预解析上述代码时,在解析到
代码块4上时,在内存中为getName申请了一块空间,解析到代码5的时候发现内存中已经有getName
了,所以就不在重新申请空间了。
在解释执行阶段,代码4要给getName赋值,也即是function(){console.log(4)}; 而代码5只是一个函数申明,
所以最终getName的值是代码4,所以输出4
3.标号3处的foo().getName(),foo()执行完对getName重新赋了值,而且foo()的返回是window对象,所以getName输出为1。
4.标号4处的getName()为什么会与标号2处的不同呢?因为标号3执行的时候,代码1中对getName赋了
新值,所以输出1
5.标号5处根据.与new的优先级关系,先执行foo.getName(),然后才执行new
6.标号6处new foo().getName(),其实就是这样var f=new foo(); f.getName(); f会先查找自身的getName方法,
没有找到便会沿着原型链查找,在上述例子中,我们在fooprototype上定义了getName,因此在原型链
上找到了getName方法。
7.标号7的这个没弄懂,后边补充。但是new new foo()会报错,所以执行应该是new (new foo().getName()); 如果是后边这种就好理解了。参照6.就是把foo.prototype.getName()new了一下
【foo.getName】

http://www.cnblogs.com/onepixel/p/5043523.html

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

http://blog.csdn.net/hsd2012/article/details/52680758

    推荐阅读