前端筆試之2019網易校招
今天剛做完網易校招的前端筆試題,總體難度不算很難,有送分題也有拉分題,不過大公司的筆試演算法題佔比最大,整套筆試題的題型與分值分佈分別是:單選題40分共20題、程式設計題60分共3題、問答題20分共2題,是牛客網的筆試。
遇到一道比較坑的單選題,在此記錄一下。
以下程式碼執行時console.log的結果是:
1 var obj = { 2x: 1, 3xyz: function () { 4with(this) { 5function con () { 6console.log(x); 7console.log(this.x); 8} 9var x = 2; 10(function() { 11con() 12})() 13con.call(this) 14} 15} 16 } 17 18 obj.xyz()
執行結果:
要理解這道題就必須搞懂每一個this指向的是什麼,所以我們可以把對應的各個this打印出來分析一波
1 var obj = { 2x: 1, 3xyz: function () { 4console.log('1', this) 5with(this) { 6function con () { 7console.log('2', this) 8console.log(x); 9console.log(this.x); 10} 11var x = 2; 12console.log('3', this); 13(function() { 14con() 15})() 16con.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。如此分析一波,這道題的答案就很清晰明瞭了。