function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
function Foor(){}
:定义了一个Foo函数Foo.getName = function(){}
: 为Foo创建一个getName的静态属性,存储一个匿名函数Foo.prototype.getName
: 为Foo的原型创建了一个getName的属性,存储一个匿名函数var getName = function(){}
: 用函数变量表达式创建了一个函数function getName(){}
: 声明了一个函数
Q & A
-
Foo.getName();
执行Foo.getName 静态属性方法 结果为:2
-
getName();
执行上下文作用域的getName函数
var getName = function(){} // 通过函数表达式创建的,由于变量也会提升,
// 因此该句会被拆成 var getName
// 和 getName = function(){} 两个部分
function getName(){} // 函数声明 会被提升
因此,顺序应该是 先提升变量 var getName, 然后 提升 函数function getName(){}
覆盖变量getName, 接着 执行 getName = function(){} 又覆盖了刚刚的函数声明,
所以 结果为: 4
- Foo().getName()
先执行Foo(), 在执行Foo()的过程中,
先执行 getName = function(){ alert(1)}, 注意到getName 前面没有var或let
这时候就需要去找getName, 找到刚才3中 getName = function(){ alert(4)}
及此时window上的getName被覆盖为了 getName = function(){alert(1)}
Foo() 执行返回this,当前this为上下文作用域,即全局 window
执行this.getName 即 window.getName()。 结果: 1
-
getName()
执行 window.getName() 结果:1
-
new Foo.getName()
点(.)的运算级高于 new,
new (Foo.getName)()
将Foo.getName 当作构造函数来执行,弹出 2
结果 2
- new Foo().getName()
new的运算级函数调用,所以不可能是Foo()先发生(纵然点(.)运算符存在,也得Foo()先执行, 所以这里的顺序应该是 new Foo() 先执行)结果3
new Foo().getName()
(new Foo()).getName ;
Foo被当作构造函数,new Foo(),原本Foo()执行是会返回this的,但由于它不是对象,
故在new的内部会返回一个继承Foo的空对象实例。
这个实例执行getName() 就会在其原型上找属性方法。 返回 3
- new new Foo().getName()
点(.)的运算符级别高于 new,按道理是先 .
单身new的运算符高于() ]
故 new Foo().getName 这里执行后,得到了一个Foo原型上的getName函数
再 new getName() 这里,原型上的getName被当作了构造函数执行用于生成新的实例.结果3
new ((new Foo()).getName)() 返回3