简介
最近我看到一道关于运算符优先级的面试题, 非常的经典. 在这里和大家分享一下。
面试题
function Foo(){
console.log('foo');
getName = function(){
console.log(1)
}
return this;
}
Foo.getName = function(){
console.log(2);
}
Foo.prototype.getName = function(){
console.log(3);
}
var getName = function(){
console.log(4)
}
function getName(){
console.log(5);
}
// 请问,下面分别打印的值是什么?
// 1.
Foo.getName();
// 2.
getName();
// 3.
Foo().getName();
// 4.
getName();
// 5.
new Foo.getName();
// 6.
new Foo().getName();
// 7.
new new Foo().getName();
解析
- #1中.调用的是Foo上的静态方法.
打印值为: 2
- #2中. 直接调用getName方法. 但是该方法定义了两遍, 一次是通过var函数表达式,一次是通过function来定义, 但是function的定义, 在解析时会前置. 所以var的函数表达式会覆盖function的定义.
打印值是4
- #3中: Foo().getName(); 执行Foo()时, 会重写外层的getName方法, 由于Foo的返回值中并不包含getName方法. 所以会执行外层的方法.
打印值是1
- #4中: 由于在#3中getName已经被覆盖. 所以这里的执行值也是
打印值是1
- #5中: new Foo.getName(); 这里涉及到new和成员访问运算符的优先级问题. new(无参数列表)的优先级是18, 成员访问是19. 所以这里先执行的是getName, 后执行的new.
打印值是2
- #6中. new Foo().getName(); 这里new后面带了(),所以优先级也是19. 这时从左到右执行. 先执行new Foo(), 后执行getName.
打印值是3
- #7中. new new Foo().getName(); 这里有两个new, 第一个new使用的是无参数调用, 优先级是18, 第二个new后面是有参数调用, 优先级是19,成员访问. 优先级也是19. 所以这里的执行顺序是: 先执行第二个new, 然后成员访问, 然后第一个new.
打印值是3
运算符的执行优先级.
其他
如果描述或理解有误, 欢迎一起讨论.