函數(Function)
是 JavaScript
裏的‘一等公民’。是由稱爲函數體的一系列語句組成。能夠當作入參,出參(返回值)使用。和對象同樣,有本身的屬性和方法。區別之處在於能夠被調用。數據類型是 function
(用 typeof
判斷),用 Object.prototype.toString.call()
判斷是 [object Function]
。若是沒有使用 retrun
語句,則默認返回 undefined
。反之則函數必須使用 return
語句來指定一個要返回的值。(使用 new
關鍵字調用一個構造函數除外,再也不是實例化一個對象)。函數執行時,this
關鍵字並不會指向正在運行的函數自己,而是指向調用該函數的對象。
函數表達式不會提高,所以在使用以前必須先聲明。和用 var
聲明變量不同。segmentfault
箭頭函數的產生緣由就是在於 this
關鍵字指向問題。它很容易讓人產生疑惑,尤爲是當函數調用層級比較多的時候。和傳統函數定義相比,語法也相對簡潔。而且沒有本身的this
,arguments
,super
或 new.target
。這些函數表達式更適用於那些原本須要匿名函數的地方,而且它們不能用做構造函數。箭頭函數 this
指向的固定化,並非由於函數內部作了處理,而是由於箭頭函數在建立的時候根本就沒有本身的 this
。app
1,函數體內的 this
對象,是定義時所在對象,而不是調用該函數的對象。
2,正由於本身自己沒有 this
對象,所以不能夠用做構造函數,不能用 call()
,apply()
,bind()
這些方法去改變 this
的指向。
3,不綁定 arguments
對象,能夠使用 rest
參數來解決。
4,嚴格模式(use strict
)中,指定的與 this
相關的規則都將被忽略。dom
var aaa = () => { 'use strict'; console.log(this); // window } var bbb = function() { 'use strict'; console.log(this); // undefined }
5,不能使用 new 操做符,不然會報錯函數
var Func = () => {}; var func = new Func(); // TypeError: Func is not a constructor
6,沒有 prototype 屬性this
var Func = () => {}; console.log(Func.prototype); // undefined
7,不能用做生成器。 yield 關鍵字一般不能在箭頭函數中使用(除非是嵌套在容許使用的函數內)。
8,箭頭函數的簡寫,能夠直接省略 return,在塊體中,必須使用明確的 return 語句。若是須要返回對象字面量的話,記得用圓括號包起來。prototype
var func = () => ({num: 1});
拋一個大佬留下的問題,有箭頭函數的 IIEF
:翻譯
(() => { console.log('執行看看'); // 執行看看 })();
這個是能夠的,可是下面的寫法就會報錯rest
(() => { console.log('執行看看'); // Uncaught SyntaxError: Unexpected token ( }());
有知道緣由的小夥伴嗎?code
2018-07-18
補充一下幾點:
1,在對象字面量上定義方法,會出現問題
以下代碼執行:對象
var obj = { i: 10, b: () => console.log(this.i, this), c: function() { console.log( this.i, this) }, d() { console.log( this.i, this) } } obj.b(); // undefined Window obj.c(); // 10 obj對象 obj.d(); // 10 obj對象
obj.b 使用箭頭函數來定義,可是調用 obj.b() 時出現了異常。由於當執行b的時候上下文仍然是window,這是由於箭頭函數已經綁定了window作爲上下文。
解決辦法就是不要在對象的方法上使用箭頭函數短語法,這樣this關鍵字會在調用時決定,而不是早早綁定在閉合的上下文中。如 obj.d()
一樣的規則也適用於給對象 prototype原型上定義方法,如
function Obj(name) { this.objName = name; } Obj.prototype.getObjName = () => { console.log(this === window); // true return this.objName; } var obj = new Obj('小紅'); obj.getObjName(); // undefined
2,動態上下文中的回調函數
this是js中很是強大的特色,他讓函數能夠根據其調用方式動態的改變上下文,而後箭頭函數直接在聲明時就綁定了this對象,因此再也不是動態的。
在客戶端,在dom元素上綁定事件監聽函數是很是廣泛的行爲,在dom事件被觸發時,回調函數中的this指向該dom,可當咱們使用箭頭函數時:
button.addEventListener('click', () => { console.log(this === window); // => true this.innerHTML = 'Clicked button'; });
由於這個回調的箭頭函數是在全局上下文中被定義的,因此他的this是window。因此當this是由目標對象決定時,咱們應該使用函數表達式:
button.addEventListener('click', function() { console.log(this === button); // => true this.innerHTML = 'Clicked button'; });
以上補充的摘自:翻譯 | ES6 箭頭函數使用禁忌