经典js计算题
经典 js 计算题
这道题摘自微信的一篇文章,坑可谓是很多,而且很细节。
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()
这个结果有点意思,主要是要理解变量提升。
var getName = function() {
alert(4);
};
function getName() {
alert(5);
}
这个的实际执行其实是:
var getName;
function getName() {
alert(5);
}
getName = function() {
alert(4);
};
所以最后的值是 4。
Foo().getName()
这里调用了 Foo 方法。Foo 方法里面对 getName 进行了赋值,但是因为没有加上 var,所以会向外查找作用域,在全局中找到了 getName,所以进行赋值。(如果没有找到的话,则会在全局中创建这个变量)。然后 return this,其实就是 window。
然后调用 window.getName(),得到的值就是 1 了。
getName()
经过了上面的分析,现在全局里面的值就是 1 了。
new Foo.getName()
这里考察了运算符的优先级
通过查询文档可以知道,(.)的优先级高于 new,所以这里实际上是将 Foo.getName 作为了构造函数,所以结果是 2。
new Foo().getName()
这里的话,带参数列表的 new 与(.)的优先级一样,所以从右向左,先执行构造函数,然后执行方法的查询调用。
这里构造函数的话,注意如果有 return 语句的话,得看 return 的是什么东西,如果不是引用类型,那么与无 return 一样!!但是如果是引用类型,就会被 return 的东西所替代。当然如果 return 的是 this 的话,就没啥关系了。所以会去原型链上找,得到的结果就是 3 了。
new new Foo().getName()
这个也是个运算符优先级问题,就是 new ((new Foo()).getName)();等于最后就是将那个原型链的方法作为了构造函数调用,得到的结果就是 3 了。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 981909093@qq.com
推荐文章
文章标题:经典js计算题
文章字数:551
本文作者:泽鹿
发布时间:2019-08-28, 16:45:23
最后更新:2019-08-28, 20:11:33
原始链接:http://panyifei.github.io/2019/08/28/技术/前端技术/经典js计算题/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。