一道关于变量作用域和上下文的JavaScript面试题

这是一道昨天的面试题:

var num = 10;
var obj = {
  num: 8,
  inner: {
    num: 6,
    print: function(){
      console.log("num: " + num + ", this.num: " + this.num);
    }
  }
}
num = 888;

下面语句输出什么?

  1. obj.inner.print();
  2. var fn = obj.inner.print;
    fn();
  3. (obj.inner.print)();
  4. (obj.inner.print = obj.inner.print)();

感谢解答~

阅读 2k
2 个回答

做这种面试题,要透过表象看本质啦,其中主要涉及的知识点有:

  • this 在函数中,如果函数调用时,有宿主对象(你这里的 obj.inner),则 this 指向该对象,如果没有,则指向全局对象(这这里是 window,因为 var num = xxx 在全局等价于 window.num = xxx),当然要除去 apply/call/bind 以及箭头函数的干涉。
  • 函数在 js 中是对象,是引用类型,因此复制给一个变量时,会将引用进行赋值,所以 fn 指向 print 函数,而和它的层级没有关系
  • js 中的 ()表达式,会计算括号中的值,所以这里的 (obj.inner.print) 等价于 obj.inner.print,这里和赋值语句不同,赋值是语句,而括号是表达式,表达式会进行求值,而求值要先执行语句
  • 接着上一点说,第四个题中就体现了这一点,我们知道 = 号赋值语句的返回值等于右边变量的值,所以 (obj.inner.print = obj.inner.print)(); 的值等价于指向 obj.inner.print 的函数,这其实和第二题中一样

我不得不吐槽一下,都 9102 年了,还要整这些实践性很低的题来考察候选人,这些东西用来丰富下技术积累也就可以了,当做面试题就有点那个了。

1: 888 6 (this为inner, this.num自然为6)
2: 888 888 (this指向window, this.num和num都是888)
3:(obj.inner.print)(); 自执行函数等价于obj.inner.print()
4: 返回一个函数再调用,等价于(function () {})()所以this指向window

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题