这是一道曾经面试过的题,当时做的时候有点懵,很综合的题,相信很多面试者都会遇到过,在这里记下来分享一下。
题目如下:
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();
答案:
2,4,1,1,2,3,3
这里我们来分析一下:
1.第一个Foo.getName(); 答案是2,显而易见,就不用多说了;
2.getName();这里面涉及到变量提升、函数提升,但是函数表达式并不会提升,而函数会首先提升,最终getName = function(){alert(4)}
会在最下面,覆盖getName函数,所以这里getName()答案为4;
3.Foo().getName();先执行Foo()函数,里面返回的getName属性函数前面没有var,所以是全局的,现在本作用域找,没有getName,再向上层作用域找,发现getName = function(){alert(4)}
,覆盖外层alert(4)为alert(1)。而Foo函数返回this,根据谁调用this就是谁的原则,此时返回的this指向为window,所以相当于执行 window.getName() ,此时window.getName()已经变成alert(1),所以答案为1;
4.getName();根据上一个函数执行,此时getName已经被覆盖变成1了,所以答案是1;
5.new Foo.getName();涉及到优先级问题,‘.’的优先级比new的高(别问为啥,查的,哈哈哈),所以此时为new (Foo.getName());所以弹出的是2;
6.new Foo().getName();运算符优先级括号高于new,相当于(new Foo()).getName();先执行Foo函数,此时Foo函数作为构造函数有返回值,返回的是实例化对象,然后调用实例化对象的getName函数,但是在Foo函数中并没有发现getName属性,所以到原型proto上找,发现Foo.prototype.getName然后执行这个方法,所以最终弹出3。
构造函数返回值(js中构造函数可以有返回值也可以没有)
-没有返回值则按照其他语言一样返回实例化对象。
-若有返回值则检查其返回值是否为引用类型。
-若返回值是引用类型,则实际返回值为这个引用类型。
7.new new Foo().getName();相当于new ((new Foo()).getName());先初始化Foo()的实力对象,然后将其原型上的getName函数作为构造函数再次new,相当于对Foo().getName()实例化,所以答案为3。
网友评论