一道經典的this面試題(複雜度兩顆星)面試
【JS腳丫系列】segmentfault
看一道題,控制檯打印出來的值是什麼?閉包
var number = 5; var obj = { number: 3, fn1: (function () { var number; this.number *= 2; number = number * 2; number = 3; return function () { var num = this.number; this.number *= 2; console.log(num); number *= 3; console.log(number); } })() } var fn1 = obj.fn1; fn1.call(null); obj.fn1(); console.log(window.number);
下面的分析過程由我(吃碼小妖)捋了一遍。app
有一點點繞,能判斷過程就能夠了。函數
【01】首先匿名自執行函數運行後,變爲this
var number = 5; var obj = { number: 3, fn1: function () { var num = this.number; this.number *= 2; console.log(num); number *= 3; console.log(number); } }
此時:code
this.number *=2 ;//this爲window,因此window.number =10;對象
number = number*2; //那麼,number 爲NaNget
number= 3;//number爲3。io
SO:
window.number =10
number =3
【02】var fn1 =obj.fn1;
那麼 fn1 就是 function(){ var num = this.number; //...}
【03】fn1.call(null) ;
若是將 null 或者是 undefined 做爲 this 的綁定對象傳入 call、apply 或者是 bind,這些值在調用時會被忽略,實際應用的是默認綁定規則。
等同於運行下面的函數:
function () { var num = window.number; window.number *= 2; console.log(num); number *= 3; console.log(number); }
而後:
var num = window.number;//num =10; window.number *= 2; // window.number = 20; console.log(num); //10 number *= 3; //3*3 = 9; console.log(number);//9
SO:
num =10;
number =9;
window.number =20;
輸出了10,9
【04】obj.fn1();
等同於運行:
fn1: function () { var num = this.number; this.number *= 2; console.log(num); number *= 3; console.log(number); }
此時:this爲obj對象。
var num = this.number; // num = 3; this.number *= 2; //obj.number*2=6 console.log(num);//3 number *= 3;// number = 27; console.log(number);//27
【05】console.log(window.number);
輸出20便可。
【06】最後結果:
//10 //9 //3 //27 //20
以爲這題很不錯,考察了多個知識點。因此推薦給你們。