第一坑:作用域
首先,有一個關於this的面試題,是這樣的:
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
主要考察的是this的指向,很明顯,this是根據上下文的執行環境決定的,obj.prop.getFullname()的上下文是obj.prop,而執行var test = obj.prop.getFullname,實際上是window.test = obj.prop.getFullname; 所以window.test()的this指向的是window,該題的結果為:先打印出Aurelio De Rosa,然后再打印出John Doe。但是,但問題還沒有結束,變個形:
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
setTimeout(function () {
console.log(this.fullname);
},100);
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
那現在呢,在setTimeout中會彈出什么?當時確實有那么幾毫秒難住了我,一想,這個setTimeout,不就相當於window.setTimeout嘛,所以,setTimeout中的this依舊指向window,在setTimeout中console打印的結果為:John Doe。
第二坑:執行順序
還是一個面試題,如下:
setTimeout(function(){ t = false; }, 1000);
while(true){}
alert('end');
問題來了:alert是否能夠彈出?為什么?問題的答案是:不能彈出來,因為JS的單線程的,永遠的單線程。在while(true)的時候陷入了死循環,就再先出不來了。關於JS的執行機制,請看這里:JavaScript 運行機制詳解:再談Event Loop這篇文章,已經很詳細了,我就不多說了。
疑惑:時間點問題
然后,同事問了我個比較詭異的問題,如下:
console.log(1);
setTimeout(function() {
console.log('timeout invoke');
console.timeEnd('timeout');
}, 2000);
console.log(2);
console.time('hard');
console.time('timeout');
for (var i = 0;i<2000000000;i++) {}
console.timeEnd('hard');
console.log(3);
在chrome下,time的標志點hard的大概時間的13秒左右,那么問題來了,setTimeout的第二個參數若為2000(2秒),timeout這個時間為多少?如果為16000(16秒),時間為多少? 經過測試發現,如果這個setTimeout的時間設置為小於13秒,setTimeout會在console.log(3)后立即執行(與hard標志點間隔特別小),如果大於13秒,就在console.log(3)后的t-13秒后觸發。 這就讓我們很是疑惑,疑惑的點在於在瀏覽器內部。
- 是什么時候開始進行setTimeout的時間打點呢?
- JS是單線程的,是哪個線程打的點呢?
而經過測試發現,是在執行到setTimeout這句話的時候, 就已經打了點,如果回頭執行隊列的時間大於setTimeout設置的時間,就再等到了那個時間在觸發setTimeout的回調, 如果小於setTimeout設置的時間,就立即執行(實際上已經延時太多了,這就是證明setTimeout不准的鐵證,其實就算沒有這種影響,也是不准的)。 具體可以參考這篇 JavaScript的單線程性質以及定時器的工作原理
但是第二個問題呢?我是這么想的:JS的單線程的,但是瀏覽器不是啊,所以是瀏覽器的另外一個線程負責的打點,如果您有不同的想法,請反饋給我吧,不勝感激。
最后
最近在研究一些原生JS的基礎以及深入,發現真是路漫漫其修遠兮,為自己加油!
