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();2

getName();4

Foo().getName();1

getName();1

new Foo.getName();2

new Foo().getName();3

new new Foo().getName();3

第一问的 Foo.getName 自然是访问Foo函数上存储的静态属性,自然是2,没什么可说的。

第二问,直接调用 getName 函数。既然是直接调用那么就是访问当前上文作用域内的叫getName的函数,所以跟1 2 3都没什么关系。此题有无数面试者回答为5。此处有两个坑,一是变量声明提升,二是函数表达式。

所有声明变量或声明函数都会被提升到当前函数的顶部。

第三问的 Foo().getName(); 先执行了Foo函数,然后调用Foo函数的返回值对象的getName属性函数。

Foo函数的第一句 getName = function () { alert (1); }; 是一句函数赋值语句,注意它没有var声明,所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是第二问中的alert(4)函数,将此变量的值赋值为 function(){alert(1)}。

第四问,直接调用getName函数,相当于 window.getName() ,因为这个变量已经被Foo函数执行时修改了,遂结果与第三问相同,为1。

第五问 new Foo.getName(); ,此处考察的是js的运算符优先级问题。点(.)的优先级高于new操作,遂相当于是:new (Foo.getName)();

第六问 new Foo().getName() ,首先看运算符优先级括号高于new,实际执行为(new Foo()).getName()。原题中,返回的是this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象。

之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,遂到当前对象的原型对象(prototype)中寻找getName,找到了,输出3。

留言

2016-05-23