箭頭函數會改變this的指向,這個你們看文檔都看到過,但是有沒有具體理解呢?
我發現本身應該可能大概是......emmmm,而後我整理了一遍,增強一下概念吧
順帶再講一下setTimeout這個函數改寫this的概念node
首先分別講一下兩位主角瀏覽器
一向風格,咱們上代碼來看問題函數
// 先給window加一個id,以便於確認以後this的指向 window.id = 0; // 聲明一個函數fn const fn = { id: 1, say: function() { console.log('id:', this.id); }, sayArrow: () => { console.log('id:', this.id); }, say1: function() { setTimeout(function() { console.log('id:', this.id); }, 1000); }, say2: function() { let that = this; setTimeout(function() { console.log('id:', that.id); }, 1000); }, say3: function() { setTimeout(() => { console.log('id:', this.id); }, 1000); }, say4: () => { setTimeout(() => { console.log('id:', this.id); }, 1000); }, say5: () => { setTimeout(function() { console.log('id:', this.id); }, 1000); }, };
好了,接下來你們來作題,不要作暈了哈this
fn.say(); fn.sayArrow(); setTimeout(fn.say, 1000); setTimeout(fn.sayArrow, 1000); setTimeout(() => fn.say(), 1000); setTimeout(() => fn.sayArrow(), 1000); fn.say1(); fn.say2(); fn.say3(); fn.say4(); fn.say5();
以上各自輸出什麼呢?接下來覈對下答案,若是全對,那ojbk了
1 0 0 0 1 0 0 1 1 0 0
若是以爲本身可能沒摸透,能夠多包幾層做用域再試試spa
接下來看代碼講緣由!code
fn.say(); /* 結果: 1 緣由: 經過fn調用的say, say是 函數聲明, this指向fn,輸出的是fn.id */ fn.sayArrow(); /* 結果: 0 緣由: 經過fn調用的say, say是 箭頭函數聲明, this指向箭頭函數聲明時做用域的this,也就是this指向window,輸出的是window.id */ setTimeout(fn.say, 1000); /* 結果: 0 緣由: 經過setTimeout調用, setTimeout改寫所傳函數的this, 也就是this指向window,輸出的是window.id */ setTimeout(fn.sayArrow, 1000); /* 結果: 0 緣由: 經過setTimeout調用, setTimeout改寫所傳函數的this, 也就是this指向window,輸出的是window.id */ setTimeout(() => fn.say(), 1000); /* 結果: 1 緣由: 經過setTimeout調用, 可是fn.say()是被箭頭函數包裹,因此fn.say()調用不受this改變的影響,緣由參考第一句輸出 ps: 等同於 setTimeout(function () { fn.say(); } , 1000); */ setTimeout(() => fn.sayArrow(), 1000); /* 結果: 0 緣由: 同上雷同,具體緣由可參考第二句輸出 ps: 等同於 setTimeout(function () { fn.sayArrow(); } , 1000); */ fn.say1(); /* 結果: 0 緣由: setTimeout改寫函數內部的this, 使其指向window, 輸出window.id */ fn.say2(); // 1 /* 結果: 1 緣由: setTimeout雖然改寫函數內部的this,可是輸出的是that.id,這個that在setTimout外面聲明,指向的是fn,因此輸出fn.id */ fn.say3(); // 1 /* 結果: 1 緣由: fn.say3函數其內部的this指向的fn,而setTimeout內部傳了一個箭頭函數,箭頭函數內部中的this就指向了fn.say3內的this,也就是fn,最後輸出fn.id */ fn.say4(); // 0 /* 結果: 0 緣由: fn.say4這個函數自己就是使用箭頭函數聲明,其內部的this指向的是箭頭函數聲明時所在的做用域,即window,並且setTimeout也是傳了一個箭頭函數,這裏面的this指向外層箭頭函數內部中的this,傳引用也指向了window,最後輸出window.id */ fn.say5(); // 0 /* 結果: 0 緣由: fn.say5用箭頭函數聲明,其內部的this指向window,並且setTimeout也會改寫內部this指向window,最後輸出window.id */
其實有一些調用其根本緣由是相同的,可是我我的喜歡各個方面去驗證一下,加深一下印象也好,勿噴
附帶說一嘴,若是有同窗在學node, node內部是沒有window對象的,window是瀏覽器規範,因此具體狀況看你在哪裏用了,不過概念是差很少的對象
寫完以爲這篇文章真的是淺談...好low啊哈哈哈哈,寫給本身看!blog