箭頭函數表達式的語法比函數表達式更短,而且沒有本身的
this
,arguments
,super
或new.target
。這些函數表達式更適用於那些本 來須要匿名函數的地方,而且它們不能用做構造函數。數組
首先:咱們先考慮一下這個箭頭函數沒有本身的this
,arguments
,super
或>首先:咱們先考慮一下這個箭頭函數沒有本身的
this,
arguments,
super或
new.target`是什麼意思?帶着問題去看下面的內容會更事半功倍。app
(參數1, 參數2, …, 參數N) => { 函數聲明 } //至關於:(參數1, 參數2, …, 參數N) =>{ return 表達式; } (參數1, 參數2, …, 參數N) => 表達式(單一) // 當只有一個參數時,圓括號是可選的: (單一參數) => {函數聲明} 單一參數 => {函數聲明} // 沒有參數的函數應該寫成一對圓括號。 () => {函數聲明}
//加括號的函數體返回對象字面表達式: 參數=> ({foo: bar}) //支持剩餘參數和默認參數 (參數1, 參數2, ...rest) => {函數聲明} (參數1 = 默認值1,參數2, …, 參數N = 默認值N) => {函數聲明} //一樣支持參數列表解構 let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
this
,不綁定this
咱們先看一下下面的代碼,函數
const Person = { 'name': 'little bear', 'age': 18, 'sayHello': function() { setTimeout(function() { console.log('我叫' + this.name + '我今年' + this.age + '歲!') }, 1000) } } console.log(Person.sayHello()) //我叫我今年undefined歲!
打印的結果是undefined
,知道是什麼緣由嗎?固然,setTimeout
方法裏面的this
指向的是window
,因此是undefined
,sayhello方法中的this
纔是指向Person的,若是按照下面的方式將sayHello中的this
賦值給封閉變量self,就能夠正確打印結果了this
const Person1 = { 'name': 'little bear', 'age': 18, 'sayHello': function() { var self = this; setTimeout(function() { console.log('我叫' + self.name + '我今年' + self.age + '歲!') }, 1000) } } console.log(Person1.sayHello());//我叫little bear我今年18歲!
咱們再看一下下面的代碼,想一想打印的結果是什麼呢?prototype
const Person3 = { 'name': 'little bear', 'age': 18, sayHello() { setTimeout(() => { console.log('我叫' + this.name + '我今年' + this.age + '歲!') }, 1000) } } console.log(Person3.sayHello());//我叫little bear我今年18歲!
這個結果是否如你所料呢?指針
箭頭函數不會建立本身的
this
,它只會從本身的做用域鏈的上一層繼承this
。所以,在下面的代碼中,傳遞給setInterval的函數內的this與 封閉函數中的this值相同rest
咱們再看看下面的代碼就應該好理解了code
const Person5 = { 'name': 'little bear', 'age': 18, sayHello: () => { setTimeout(() => { console.log('我叫' + this.name + '我今年' + this.age + '歲!') }, 1000) } } Person5.sayHello();//我叫我今年undefined歲!
封閉函數的this
指向的是外部對象window
,setTimeout
繼承上一層this
,因此也是指向的window
;對象
經過 call 或 apply 調用繼承
首先咱們回顧一下 call
跟 apply
他們各自的定義:
它們的共同之處:
都「能夠用來代替另外一個對象調用一個方法,將一個函數的對象上下文從初始的上下文改變爲由thisObj指定的新對象」。
它們的不一樣之處:
咱們先來看一下下面的代碼,思考一下打印的結果,
var adder = { base : 1, add : function(a) { var f = v => v + this.base; return f(a); }, addThruCall: function(a) { var f = v => v + this.base; var b = { base : 2 }; return f.call(b, a); } }; console.log(adder.add(1)); // 輸出 2 console.log(adder.addThruCall(1)); // 仍然輸出 2(而不是3 ——譯者注)
結果:
因爲 箭頭函數沒有本身的this指針,經過 call() 或 apply() 方法調用一個函數時,只能傳遞參數(不能綁定this---譯者注),他們的第一個參數會被忽略。(這種現象對於bind方法一樣成立---譯者注)
咱們都知道函數內部,argument
是一個做爲函數輸入的值-原始數據或對象
var arguments = [5, 6, 7]; function person1(a, b, c) { console.log(arguments); } person1(1, 2);//arguments[1,2] var arr1 = () => { return arguments; } console.log(arr1());//[5,6,7] var arr2 = (a) => { return arguments; } console.log(arr2(1));//[5,6,7]
從上就能夠看出,通常的函數是綁定了Arguments
對象,而箭頭函數沒有綁定
看下面的代碼箭頭函數中的arguments
只是引用了封閉做用域內的arguments
var arguments = [1, 2, 3]; var arr = () => arguments[0]; arr(); // 1 function foo(n) { var f = () => arguments[0] + n; // 隱式綁定 foo 函數的 arguments 對象. arguments[0] 是 n return f(); } foo(1); // 2
箭頭函數不能用做構造器,和 new一塊兒用會拋出錯誤。
var Foo = () => {}; var foo = new Foo(); // TypeError: Foo is not a constructor
箭頭函數沒有prototype屬性。
var Foo = () => {}; console.log(Foo.prototype); // undefined
yield
關鍵字一般不能在箭頭函數中使用(除非是嵌套在容許使用的函數內)。所以,箭頭函數不能用做生成器。