一道看似简单的面试题,其中考察了很多知识点
例如:js优先级运算符 变量声明提升 原型 this指向
//写出以下输出结果
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等于一个方法,之后return出this 看到这里要想到this在普通函数中的指向是window
所以这里的return的是window
对象
第二行:
给Foo构造函数设置一个静态属性getName等于一个方法—(JavaScript中函数也是对象,可以直接加 . 赋值获取)
第三行:
在Foo这个构造函数的原型上设置一个属性也是getName等于一个方法
第四行,第五行:
变量声明一个getName,和函数声明getName,此时要注意
变量声明和函数声明同一个名字的变量函数声明会将变量声明的表达式覆盖也就是变量提升和函数声明提升
注意:变量提升在函数声明前
提升后的代码
function Foo() {
getName = function () { alert(1); };
return this;
}
var getName; // ----------变更
function getName() { alert(5); } // ----------变更
Foo.getName = function () { alert(2); };
Foo.prototype.getName = function () { alert(3); };
getName = function () { alert(4); }; // ----------变更
以下输出结果:
//-------------------------------------第一题-------------------------------------
Foo.getName();
//查看Foo的静态属性自调用,自然就是2
//-------------------------------------第二题-------------------------------------
getName();
//提升后的代码变量声明的getName,将之前函数声明的getName覆盖,结果是4
//-------------------------------------第三题-------------------------------------
Foo().getName();
//Foo()执行里面函数时会将getName重新赋值,它先找var变量声明getName,
//Foo作用域内没有,此时会向外找,此时是getName()即为this.getName()也就是window.getName()
//为4,然后将它重新赋值为1,所以执行1
//-------------------------------------第四题-------------------------------------
getName();
//此时的getName在上一步已经覆盖赋值,所以执行结果为1
//-------------------------------------第五题-------------------------------------
new Foo.getName();
//相当于 new( Foo.getName() )
//所以结果也是2
//注意: new Foo属于 new(无参数列表)权重或者优先级为18,小于“.”。所以先执行Foo.getName()
//-------------------------------------第六题-------------------------------------
new Foo().getName();
//相当于 ( new Foo() ).getName()
//new Foo()实例化了构造函数Foo 返回this为自身的这个构造函数,然而自身并没有getName这个属性
//此时会找原型prototype,从而输出3----------------此时考察原型,实例,构造函数的关系
//注意: new Foo()属于 new(带参数列表)权重或者优先级为19,等于“.”。所以从左至右执行
//-------------------------------------第七题-------------------------------------
new new Foo().getName();
//相当于 new( new Foo().getName() )
//所以先执行上题的结果后,输出仍然是3
//=====================================================================================
以上是我面试后,总结此题,也有不足希望大佬们多多批评指正!!