帶給我this的煩惱

this的第一次接觸是做一個父容器事件代理的DEMO,當時還不會jquery;

<ul class="ct">
    <li>內容1</li>
    <li>內容2</li>
    <li>內容3</li>
</ul>
var ct=document.querySelector('.ct');
ct.addEventListener('click',function(e){
    console.log(e.target.innerText);
});

第一次接觸this,感覺這個太厲害了,就是誰調用就是誰;后來遇到這樣一個DEMO

function foo(){
    console.log(this);
    function foo2(){
        console.log(this);
    }
    foo2();
}
foo();

我以為第一個結果是window,第二個結果是foo2,結果控制臺的輸入狠狠的打臉了!

輸出結果

當時我就懵逼了,因為從"元素之力"的世界來,"零一世界"的運作原理還知之甚少,后來經過別人點撥,這個是由于堆棧,是計算機的一個原理;

后來我想想,應該是我在全局環境下調用了foo(),然后window將整個foo()給推入了堆棧,第一個輸出為window理所應當,那么foo(2)也是被window給推進堆棧的,"幕后黑手"也是window,這樣應該就解釋了,這個demo中第二個輸出的結果還是window,雖然是函數內部嵌套函數,但this依舊指向了window;

手賤的我又看到了call和apply,這種切換this的手段

var obj1 = {
    name:'ran',
    fn:function(){
        console.log(this);
    }
};

obj1.fn();

var fn2 = obj1.fn;
fn2();

fn2.call(obj1);

為什么會這樣呢?

  • 第一個:obj.fn()是obj去調用fn的,當然第一個是他,這個沒有什么異議;
  • 第二個陷阱就來了,在全局環境下聲明fn2=obj.fn;再去執行fn2,這個時候相當于再全局環境下執行
function(){
    console.log(this);
}

一開始,我也犯了迷糊,明明fn在obj之內,怎么又指向全局了,后來我想明白了,這只是一個賦值,讓fn2擁有這個函數罷了,相當于obj是一個銀行,fn就是100快,現在銀行外面的fn2從銀行取出一個100快,總不能因為都是100快,就說fn2的錢還是銀行的吧;

  • 第三個:用call切換了,函數的作用域,打到了切換this的指向,本來fn2的作用域是全局,this是指向window的,結果被call切換到了obj里面,自然把黑鍋又給了obj,那么這個this就指向了obj,最后輸出也是obj,而不是window;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 與其他語言相比,函數的this關鍵字在JavaScript中的表現略有不同,此外,在嚴格模式和非嚴格模式之間也會有...
    codingC閱讀 587評論 0 0
  • Javascript 中的 this,有時候讓人迷惑,所以總結了一下關于this指向的問題。 在函數中 this ...
    lxt410725閱讀 475評論 0 1
  • 本文最初發布于http://szhshp.org轉載請注明 This關鍵字 同時如果不使用this我們可以傳入一個...
    szhielelp閱讀 495評論 0 0
  • 1.函數調用棧和調用位置 在函數執行的時候,會有一個活動記錄(也叫執行上下文)來記錄函數的調用順序,這個就是函數調...
    lightNate閱讀 543評論 1 14
  • 午后小憩片刻,窗外傳來陣陣蟬鳴聲。思緒不禁長出了翅膀,飛回離別多年的老家。 老家的后院靠河,河岸邊長滿了郁郁蔥蔥的...
    林木森深深閱讀 667評論 0 48