前端笔试之网易校招

时间:2024-01-21 16:02:14

今天刚做完网易校招的前端笔试题,总体难度不算很难,有送分题也有拉分题,不过大公司的笔试算法题占比最大,整套笔试题的题型与分值分布分别是:单选题40分共20题、编程题60分共3题、问答题20分共2题,是牛客网的笔试。

遇到一道比较坑的单选题,在此记录一下。

以下代码执行时console.log的结果是:

 1 var obj = {
 2   x: 1,
 3   xyz: function () {
 4       with(this) {
 5           function con () {
 6             console.log(x);
 7             console.log(this.x);
 8           }
 9           var x = 2;
10           (function() {
11               con()
12           })()
13           con.call(this)
14       }
15   }
16 }
17 
18 obj.xyz()

执行结果:

 要理解这道题就必须搞懂每一个this指向的是什么,所以我们可以把对应的各个this打印出来分析一波

 1 var obj = {
 2   x: 1,
 3   xyz: function () {
 4       console.log(\'1\', this)
 5       with(this) {
 6         function con () {
 7           console.log(\'2\', this)
 8           console.log(x);
 9           console.log(this.x);
10         }
11         var x = 2;
12         console.log(\'3\', this);
13         (function() {
14           con()
15         })()
16         con.call(this)
17       }
18   }
19 }
20 
21 obj.xyz()

执行结果如下:

从执行顺序分析,1号this打印出来的是obj对象,也就是说with传进去的是obj对象,在with代码块里,首先声明了con函数,然后再执行了var x=2;这一段代码,而with修改了词法作用域,把with代码块里的上下文改为obj对象,那么这段代码等同于obj.x = 2,即把obj对象里的x属性修改为2,接着打印了3号this,值为obj对象,验证了with代码块的上下文是obj对象。接着执行了一个立即执行函数,函数里调用了con函数。在《你不知道的JavaScript上卷》第2章里有提到函数里this的绑定取决于函数的调用方式,而于函数声明的位置无关,this的绑定规则有四个:默认绑定(独立函数调用)、隐式绑定(obj.foo())、显示绑定(call()和apply())和new绑定。显然,立即执行函数里直接调用con函数,属于默认绑定,默认绑定this会指向全局对象(window或global),所以第9行console.log(this.x)打印的是window.x,而全局对象window中并没有定义x,因此打印出undefined,而第8行console.log(x)打印的是当前词法作用域里的x,即为obj.x,打印出2。接着分析第16行代码con.call(this)相当于con.call(obj),显然,使用call()方法调用con函数,显示绑定this指向obj,所以第9行console.log(this.x)打印的是obj.x,即为2,然后第8行同理打印的是当前词法作用域里的x。如此分析一波,这道题的答案就很清晰明了了。