一道前端的面试题 js
2021-03-08 09:26
作者:Wscats
链接:https://github.com/Wscats/articles/issues/85
题目
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();
这几天面试上几次碰上这道经典的题目,特地从头到尾来分析一次答案,这道题的经典之处在于它综合考察了面试者的JavaScript的综合能力,包含了变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级等知识,此题在网上也有部分相关的解释,当然我觉得有部分解释还欠妥,不够清晰,特地重头到尾来分析一次,当然我们会把最终答案放在后面,并把此题再改高一点点难度,改进版也放在最后,方便面试官在出题的时候有个参考,更多详情可关注本文作者@Wscats
第一问
先看此题的上半部分做了什么,首先定义了一个叫Foo的函数,之后为Foo创建了一个叫getName的静态属性存储了一个匿名函数,之后为Foo的原型对象新创建了一个叫getName的匿名函数。之后又通过函数变量表达式创建了一个getName的函数,最后再声明一个叫getName函数。
第一问的Foo.getName自然是访问Foo函数上存储的静态属性,答案自然是2,这里就不需要解释太多的,一般来说第一问对于稍微懂JS基础的同学来说应该是没问题的,当然我们可以用下面的代码来回顾一下基础,先加深一下了解
function User(name) {
var name = name; //私有属性
this.name = name; //公有属性
function getName() { //私有方法
return name;
}
}
User.prototype.getName = function() { //公有方法
return this.name;
}
User.name = ‘Wscats‘; //静态属性
User.getName = function() { //静态方法
return this.name;
}
var Wscat = new User(‘Wscats‘); //实例化
注意下面这几点:
-
调用公有方法,公有属性,我们必需先实例化对象,也就是用new操作符实化对象,就可构造函数实例化对象的方法和属性,并且公有方法是不能调用私有方法和静态方法的
-
静态方法和静态属性就是我们无需实例化就可以调用
-
而对象的私有方法和属性,外部是不可以访问的
第二问
第二问,直接调用getName函数。既然是直接调用那么就是访问当前上文作用域内的叫getName的函数,所以这里应该直接把关注点放在4和5上,跟1 2 3都没什么关系。当然后来我问了我的几个同事他们大多数回答了5。此处其实有两个坑,一是变量声明提升,二是函数表达式和函数声明的区别。
我们来看看为什么,可参考(1)关于Javascript的函数声明和函数表达式 (2)关于JavaScript的变量提升
在Javascript中,定义函数有两种类型
函数声明
// 函数声明
function wscat(type) {
return type === "wscat";
}
函数表达式
// 函数表达式
var oaoafly = function(type) {
return type === "oaoafly";
}
上一篇:java集合框架: 泛型
下一篇:css 3D转换