摘要:對象的指向是可變的,但是在箭頭函數中,它是固定的。同樣的由于箭頭函數沒有自己的所以傳統的顯性綁定無效內部的指向外部在的學習中,的指向問題一直是個難點,特別是在對象方法中使用時,必須更加小心。由此箭頭函數在很大程度上減少了我們的困擾。
什么是箭頭函數 用法
ES6 允許使用“箭頭”(=>)定義函數
測試
var p1 = document.getElementById("test1"); p1.addEventListener("click", () => { p1.style.color = "red"; }, false);
在es5中相當于
var p1 = document.getElementById("test1"); p1.addEventListener("click", function () { //直接通過dom的方法改變顏色 this.style.color = "red"; },false);
但是我們思考一個問題——當我們把第一段代碼中的p1換成this時
this會指向哪里
p1.addEventListener("click", () => { this.style.color = "red";// "color" is not undefined }, false);
這時我們就會想this為什么沒有作用,而在es5中this是指向了p1
箭頭函數有個使用注意點。函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
this對象的指向是可變的,但是在箭頭函數中,它是固定的。
function foo() { setTimeout(() => { console.log("id:", this.id); }, 100); } var id = 21; foo.call({ id: 42 }); // id: 42
上面代碼中,setTimeout的參數是一個箭頭函數,這個箭頭函數的定義生效是在foo函數生成時,而它的真正執行要等到100毫秒后。如果是普通函數,執行時this應該指向全局對象window,這時應該輸出21。但是,箭頭函數導致this總是指向函數定義生效時所在的對象(本例是{id: 42}),所以輸出的是42
箭頭函數的thisthis指向的固定化,并不是因為箭頭函數內部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this,導致內部的this就是外層代碼塊的this。正是因為它沒有this,所以也就不能用作構造函數。
// ES6 function foo() { setTimeout(() => { console.log("id:", this.id); }, 100); } // ES5 function foo() { var _this = this; setTimeout(function () { console.log("id:", _this.id); }, 100); }
上面代碼中,轉換后的es5清楚地說明了,箭頭函數里面根本沒有自己的this,而是引用外層的this。
由于箭頭函數沒有自己的this,所以當然也就不能用call()、apply()、bind()這些方法去改變this的指向。
(function() { return [ (() => this.x).bind({ x: "inner" })() ]; }).call({ x: "outer" }); // ["outer"]
同樣的由于箭頭函數沒有自己的this 所以bind傳統的顯性綁定無效 內部的this指向外部this
在javascript的學習中, this的指向問題一直是個難點,特別是在對象方法中使用this時,必須更加小心。由此箭頭函數在很大程度上減少了我們的困擾。
話又說回來,當我們使用箭頭函數時不使用常規的四種this綁定,又該怎么決定this的指向問題呢?
箭頭函數是根據外層(函數或者全局)作用域來決定this
讓我們看看箭頭函數的此法作用域:
function foo() { //返回箭頭函數 return(a) => { //this 繼承自foo() console.log(this.a); }; } var obj1 = { a:2 }; var obj2 ={ a:3 }; var bar = foo.call(obj1); bar.call(obj2); //是2, 不是3!!!
foo()內部創建的箭頭函數會捕獲調用時foo()的this。由于foo()的this綁定到了obj1,所以bar(引用箭頭函數)的this也會綁定到obj1,上文說過箭頭函數this對象的指向是固定的所以后面的call修改不了綁定,即使是new也不行。
箭頭函數可以像bind()一樣確保函數的this被綁定到指定對象上,此外, 其重要性還體現在它更常見的詞法作用域取代了傳統的this的機制。實際上, 在ES6之前我們就已經在使用一種集合和箭頭函數完全一樣的模式了。
function foo() { var self = this; setTimeout(function() { console.log(self.a) },100) } var obj = { a:2 }; foo.call(obj);
和箭頭函數一樣self = this 看起來都可以取代bind(), 但是從本質上來看,它們是想代替this這個機制。
注意如果經常編寫this風格的代碼,又喜歡用箭頭函數或者self= this的方法來否定this機制。
那么或許你應當:
只使用詞法作用域并完全摒棄錯誤的this風格
完全采用this風格,在必要時仍使用bind(), 避免使用箭頭函數或者self = this。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91381.html
摘要:回顧我們先來回顧下箭頭函數的基本語法。主要區別包括沒有箭頭函數沒有,所以需要通過查找作用域鏈來確定的值。箭頭函數并沒有方法,不能被用作構造函數,如果通過的方式調用,會報錯。 回顧 我們先來回顧下箭頭函數的基本語法。 ES6 增加了箭頭函數: let func = value => value; 相當于: let func = function (value) { return ...
摘要:也就是說箭頭函數的的值不再根據調用時上下文確定,而是像普通變量那樣根據定義時的作用域鏈進行查找。箭頭函數中的依然要根據定義時的作用域鏈進行查找。知乎這篇文章對箭頭函數的一些不適合的場景進行了總結,可以作為參考。 es6 - 箭頭函數 哇,箭頭函數...,聽起來好NB,但是如果你知道它是因為使用了=>這樣類似箭頭的符號 ,所以才叫箭頭函數。 瞬間感覺:呵,這名字起的...。 es6增加了...
摘要:沒有箭頭函數沒有自己的對象,這不一定是件壞事,因為箭頭函數可以訪問外圍函數的對象那如果我們就是要訪問箭頭函數的參數呢你可以通過命名參數或者參數的形式訪問參數不能通過關鍵字調用函數有兩個內部方法和。 1、基本語法回顧 我們先來回顧下箭頭函數的基本語法。ES6 增加了箭頭函數: var f = v => v; // 等同于 var f = function (v) { return ...
摘要:但是,的本質仍然是函數,是構造函數的另外一種寫法。報錯原生構造函數的繼承對于一些原生的構造函數,比如,,,等,在是無法通過方法實現原生函數的內部屬性,原生函數內部的無法綁定,內部屬性獲得不了。 在沒有學習 ES6 之前,學習 React,真的是一件非常痛苦的事情。即使之前你對 ES5 有著很好的基礎,包括閉包、函數、原型鏈和繼承,但是 React 中已經普遍使用 ES6 的語法,包括 ...
摘要:關于的學習總結昨天寫了第一篇,主要是關于變量聲明關鍵字和,新增類型以及模板字符串,今天準備寫第二篇,里面的函數部分,新增了箭頭函數,參數以及參數默認值。,這次我們在調用函數大的時候,兩個參數全部傳遞了值,因此返回。 關于ES6的學習總結,昨天寫了第一篇,主要是關于變量聲明關鍵字let和const,新增類型Symbol以及模板字符串,今天準備寫第二篇,ES6里面的函數部分,ES6新增了箭...
閱讀 4391·2021-11-19 09:59
閱讀 3318·2021-10-12 10:12
閱讀 2630·2021-09-22 15:25
閱讀 3320·2019-08-30 15:55
閱讀 1182·2019-08-29 11:27
閱讀 1463·2019-08-28 18:06
閱讀 2735·2019-08-26 13:41
閱讀 2554·2019-08-26 13:41