今天剛作完網易校招的前端筆試題,整體難度不算很難,有送分題也有拉分題,不過大公司的筆試算法題佔比最大,整套筆試題的題型與分值分佈分別是:單選題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()
執行結果:app
要理解這道題就必須搞懂每個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()
執行結果以下:this
從執行順序分析,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。如此分析一波,這道題的答案就很清晰明瞭了。spa