家好,很高興又見面了,我是姜茶的編程筆記,我們一起學習前端相關領域技術,共同進步,也歡迎大家關注、點贊、收藏、轉發,您的支持是我不斷創作的動力
我們來聊聊箭頭函數(就是下面這個東西)!箭頭函數的語法比傳統的函數表達式更簡潔,而且它們沒有自己的 this、arguments、super 或 new.target。它們非常適合用在需要匿名函數的地方,同時不能作為構造函數使用。
// 當只有一個參數時,圓括號不是必須的
(singleParam) => { statements }
singleParam => { statements }
// 沒有參數的函數必須加圓括號
() => { statements }
箭頭函數有兩個主要優點:
1?? 語法更簡潔
2?? 不會綁定 this
沒有自己的 this
箭頭函數不會創建自己的 this,它只會繼承外層作用域的 this。
function Person() {
this.age = 0;
setInterval(() => {
// this 正確地指向 p 實例
console.log(this === p); // true
this.age++;
}, 1000);
}
var p = new Person();
由于 this 是詞法綁定的,嚴格模式中與 this 相關的規則將被忽略。
var f = () => { 'use strict'; return this; };
f() === window; // 或 global
因為箭頭函數沒有自己的 this,使用這些方法調用時只能傳遞參數,它們的第一個參數 this 會被忽略。
let adder = {
base: 1,
add: function (a) {
console.log(this === adder); // true
let f = (v) => v + this.base;
return f(a);
},
addThruCall: function (a) {
let f = (v) => {
console.log(this === adder); // true
console.log(`v 的值是 ${v},this.base 的值是 ${this.base}`); // 'v 的值是 1,this.base 的值是 1'
return v + this.base;
};
let b = { base: 3 };
// call() 方法不能綁定 this 為 b 對象,第一個參數 b 被忽略了
return f.call(b, a);
}
};
console.log(adder.add(1)); // 輸出 2
console.log(adder.addThruCall(1)); // 輸出 2
箭頭函數沒有 this 綁定。
"use strict";
var obj = {
i: 10,
b: () => console.log(this.i, this), // undefined, Window{...}
c: function () {
console.log(this.i, this); // 10, Object {...}
}
};
obj.b();
obj.c();
箭頭函數不能用作構造函數,用 new 調用會拋出錯誤。
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor
ES6 的箭頭函數表達式是匿名函數的一種簡寫方式:
// 匿名函數
let show = function () {
console.log("匿名函數")
};
show(); // "匿名函數"
let show1 = () => console.log("匿名函數");
show1(); // "匿名函數"
不過,箭頭函數和傳統匿名函數在實際操作中還是有一些區別的。
如果你有任何問題或建議,歡迎在評論區留言交流!祝你編程愉快!
建函數還有另外一種非常簡單的語法,并且這種方法通常比函數表達式更好。
它被稱為“箭頭函數”,因為它看起來像這樣:
let func = (arg1, arg2, ..., argN) => expression;
這里創建了一個函數 func,它接受參數 arg1..argN,然后使用參數對右側的 expression 求值并返回其結果。
換句話說,它是下面這段代碼的更短的版本:
let func = function(arg1, arg2, ..., argN) {
return expression;
};
讓我們來看一個具體的例子:
let sum = (a, b) => a + b;
/* 這個箭頭函數是下面這個函數的更短的版本:
let sum = function(a, b) {
return a + b;
};
*/
alert( sum(1, 2) ); // 3
可以看到 (a, b) => a + b 表示一個函數接受兩個名為 a 和 b 的參數。在執行時,它將對表達式 a + b 求值,并返回計算結果。
箭頭函數可以像函數表達式一樣使用。
例如,動態創建一個函數:
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ?
() => alert('Hello') :
() => alert("Greetings!");
welcome();
一開始,箭頭函數可能看起來并不熟悉,也不容易讀懂,但一旦我們看習慣了之后,這種情況很快就會改變。
箭頭函數對于簡單的單行行為(action)來說非常方便,尤其是當我們懶得打太多字的時候。
上面的例子從 => 的左側獲取參數,然后使用參數計算右側表達式的值。
但有時我們需要更復雜一點的東西,比如多行的表達式或語句。這也是可以做到的,但是我們應該用花括號括起來。然后使用一個普通的 return 將需要返回的值進行返回。
就像這樣:
let sum = (a, b) => { // 花括號表示開始一個多行函數
let result = a + b;
return result; // 如果我們使用了花括號,那么我們需要一個顯式的 “return”
};
alert( sum(1, 2) ); // 3
更多內容
在這里,我們贊揚了箭頭函數的簡潔性。但還不止這些!
箭頭函數還有其他有趣的特性。
為了更深入地學習它們,我們首先需要了解一些 JavaScript 其他方面的知識,因此我們將在后面的 深入理解箭頭函數 一章中再繼續研究箭頭函數。
現在,我們已經可以用箭頭函數進行單行行為和回調了。
對于一行代碼的函數來說,箭頭函數是相當方便的。它具體有兩種:
用箭頭函數重寫下面的函數表達式:
function ask(question, yes, no) {
if (confirm(question)) yes();
else no();
}
ask(
"Do you agree?",
function() { alert("You agreed."); },
function() { alert("You canceled the execution."); }
);
解決方案
function ask(question, yes, no) {
if (confirm(question)) yes();
else no();
}
ask(
"Do you agree?",
() => alert("You agreed."),
() => alert("You canceled the execution.")
);
是不是看起來精簡多了?
頭函數(Arrow Function)是ES6新增的特性,在網上看了一篇個人博客的講解,寫的例子里面居然還有聲明的變量沒有被使用,卻還在招攬學生做IT培訓,真的誤人子弟。
為了說明箭頭函數,我們先寫個簡單的代碼:
const domain_list = [
'www.abot.cn',
'www.tseo.cn',
'www.weiduke.com',
'yanyubao.tseo.cn'
];
console.log(domain_list.map(domain_item => domain_item.length));
// expected output: Array [11, 11, 15, 16]
關于JavaScript中map函數的使用,這里不贅述,不懂的抓緊惡補。
重點看第8行。
domain_item => domain_item.length
等價于以下寫法:
function(domain_item) {return domain_item.length}
所以以上代碼的ES5的寫法為:
const domain_list = [
'www.abot.cn',
'www.tseo.cn',
'www.weiduke.com',
'yanyubao.tseo.cn'
];
console.log(domain_list.map(function(domain_item) {
return domain_item.length;
}));
// expected output: Array [11, 11, 15, 16]
總結總結一下,ES6的基本語法
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
//相當于:(param1, param2, …, paramN) =>{ return expression; }
// 當只有一個參數時,圓括號是可選的:
(singleParam) => { statements }
singleParam => { statements }
// 沒有參數的函數應該寫成一對圓括號。
() => { statements }
對照以上的例子,什么是箭頭函數應該一目了然了。
this一般是這樣被定義的:
function Person() {
// Person() 構造函數定義 `this`作為它自己的實例.
this.age = 0;
setInterval(function growUp() {
// 在非嚴格模式, growUp()函數定義 `this`作為全局對象,
// 與在 Person()構造函數中定義的 `this`并不相同.
this.age++;
}, 1000);
}
var p = new Person();
在ECMAScript 3/5中,通過將this值分配給封閉的變量,可以解決this問題。
function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
// 回調引用的是`that`變量, 其值是預期的對象.
that.age++;
}, 1000);
}
或者,可以創建綁定函數,以便將預先分配的this值傳遞到綁定的目標函數(上述示例中的growUp()函數)。
箭頭函數不會創建自己的this,它只會從自己的作用域鏈的上一層繼承this。因此,在下面的代碼中,傳遞給setInterval的函數內的this與封閉函數中的this值相同:
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| 正確地指向 p 實例
}, 1000);
}
var p = new Person();
如果不理解以上代碼,那么再強調一遍:因為箭頭函數沒有this,所以setInterval函數中的箭頭函數的this,只能是他的上一級函數的this。如果說到這樣還不理解,建議惡補語文。
箭頭函數的進階知識,包括:
感興趣的小伙伴可以自個去研究。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。