做过很多前端笔试题,有些题看起来简单,就是读程序写结果,但要么做错,要么对答案不确定,这里找到一道比较综合的题目
function Foo() { //定义了一个名叫Foo的函数
getName = function () { alert (1); }; //(1)函数内定义了一个函数变量
return this;
}
Foo.getName = function () { alert (2);}; //(2)创建了Foo的静态属性
Foo.prototype.getName = function () { alert (3);}; //(3)定义了Foo函数原型对象上的getName函数
var getName = function () { alert (4);}; //(4)通过函数变量表达式定义了一个叫getName的函数
function getName() { alert (5);} //(5)声明了一个getName函数
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
第一题:
Foo.getName(); //2
Foo.getName; // function(){alert(2);}
这道题比较简单,Foo函数上的getName函数,执行的是第(2)句
第二题:
getName(); //4
我多次做这道题都会认为答案是5,其实不然。
因为变量声明提升,所以(4)拆分成两句,var getName; getName = function(){alert(3);}
其中var getName
函数表达式被提升,但getName = function(){alert(3);}则不提升,
(5)函数声明function getName
同样提升,结果顺序就变为
function Foo() {
getName = function () { alert (1); };
return this;
}
var getName; //变量声明提升
function getName () {alert(5);}; //变量声明提升,getName()的结果为alert(5)
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
getName = function () { alert (4);}; //覆盖了getName()的结果
因此,getName()的结果为4.
第三题
Foo().getName(); //1
先执行Foo()函数,再调用其返回值对象的getName属性函数。
(1)句没有var声明,就先在Foo()里寻找getName声明,没有找到,就在外层作用域中寻找,在第(4)句找到了var getName
,将此变量的值赋值为function(){alert(1);}
。
Foo()返回值对象this指代的是调用这个函数的对象,在这里相当于window
,则Foo().getName()
相当于window.getName()
,而window
的getName()
已经被赋值为function(){alert(1);}
,所以结果就为1。
Foo.getName
和Foo().getName
的区别
function Foo(){
var getName = 'Zoe';
}
Foo.getName; //undefined
Foo().getName; //'Zoe'
第四题
getName(); //相当于调用window.getName(),结果为1
第五题
new Foo.getName(); //2
成员访问运算符(.)的优先级大于new
,小括号()的优先级又大于(.)
所以问题改写成
new (Foo.getName)();相当于把getName当做构造函数在执行
第六题
new Foo().getName(); //3
同样因为优先级,改写成
(new Foo()).getName();
var f = Foo();
f.getName();
首先构建了一个Foo函数的实例化对象,再调用对象的getName属性,由于Foo构造函数没有添加getName属性,所以向上查找到原型对象,即(3)句,得到结果3
我犯过的一个错误,将(1)看成Foo函数的属性,其实不是的,那只是函数体内的一个变量,只能在函数体内访问,如果要表示函数属性,需要写成this.getName
第七题
new new Foo().getName(); //3
改写成
new ((new Foo()).getName)();
var f = new Foo();
var x = f.getName;
new x();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。