摘要:基本用法允許使用箭頭定義函數。不可以當作構造函數,也就是說,不可以使用命令,否則會拋出一個錯誤。箭頭函數綁定,很大程度上解決了這個困擾。函數綁定箭頭函數可以綁定對象,大大減少了顯式綁定對象的寫法。
基本用法
ES6允許使用“箭頭”(=>)定義函數。
var f = v => v;
上面的箭頭函數等同于:
var f = function(v) {
return v;
};
如果箭頭函數不需要參數或需要多個參數,就使用一個圓括號代表參數部分。
復制代碼
var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
復制代碼
如果箭頭函數的代碼塊部分多于一條語句,就要使用大括號將它們括起來,并且使用return語句返回。
var sum = (num1, num2) => { return num1 + num2; }
由于大括號被解釋為代碼塊,所以如果箭頭函數直接返回一個對象,必須在對象外面加上括號。
var getTempItem = id => ({ id: id, name: "Temp" });
箭頭函數可以與變量解構結合使用。
復制代碼
const full = ({ first, last }) => first + " " + last;
// 等同于
function full(person) {
return person.first + " " + person.last;
}
復制代碼
使用注意點
箭頭函數有幾個使用注意點。
(1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
(2)不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。
(3)不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用Rest參數代替。
(4)不可以使用yield命令,因此箭頭函數不能用作Generator函數。
this指向的固定化,并不是因為箭頭函數內部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this,導致內部的this就是外層代碼塊的this。正是因為它沒有this,所以也就不能用作構造函數。
除了this,以下三個變量在箭頭函數之中也是不存在的,指向外層函數的對應變量:arguments、super、new.target。
復制代碼
function foo() {
setTimeout(() => {
console.log("args:", arguments);
}, 100);
}
foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]
復制代碼
上面代碼中,箭頭函數內部的變量arguments,其實是函數foo的arguments變量。
另外,由于箭頭函數沒有自己的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對象的寫法(call、apply、bind)。但是,箭頭函數并不適用于所有場合,所以ES7提出了“函數綁定”(function bind)運算符,用來取代call、apply、bind調用。雖然該語法還是ES7的一個提案,但是Babel轉碼器已經支持。
函數綁定運算符是并排的兩個雙冒號(::),雙冒號左邊是一個對象,右邊是一個函數。該運算符會自動將左邊的對象,作為上下文環境(即this對象),綁定到右邊的函數上面。
復制代碼
foo::bar;
// 等同于
bar.bind(foo);
foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);
const hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
return obj::hasOwnProperty(key);
}
復制代碼
如果雙冒號左邊為空,右邊是一個對象的方法,則等于將該方法綁定在該對象上面。
復制代碼
var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;
let log = ::console.log;
// 等同于
var log = console.log.bind(console);
復制代碼
由于雙冒號運算符返回的還是原對象,因此可以采用鏈式寫法。
尾調用優化
什么是尾調用?
尾調用(Tail Call)是函數式編程的一個重要概念,本身非常簡單,一句話就能說清楚,就是指某個函數的最后一步是調用另一個函數。
function f(x){
return g(x);
}
上面代碼中,函數f的最后一步是調用函數g,這就叫尾調用。
“尾調用優化”(Tail call optimization),即只保留內層函數的調用幀。如果所有函數都是尾調用,那么完全可以做到每次執行時,調用幀只有一項,這將大大節省內存。這就是“尾調用優化”的意義。
嚴格模式
ES6的尾調用優化只在嚴格模式下開啟,正常模式是無效的。
這是因為在正常模式下,函數內部有兩個變量,可以跟蹤函數的調用棧。
func.arguments:返回調用時函數的參數。
func.caller:返回調用當前函數的那個函數。
尾調用優化發生時,函數的調用棧會改寫,因此上面兩個變量就會失真。嚴格模式禁用這兩個變量,所以尾調用模式僅在嚴格模式下生效。
復制代碼
function restricted() {
"use strict";
restricted.caller; // 報錯
restricted.arguments; // 報錯
}
restricted();
復制代碼
箭頭函數與常規函數對比
一個箭頭函數與一個普通的函數在兩個方面不一樣:
下列變量的構造是詞法的: arguments , super , this , new.target
不能被用作構造函數:沒有內部方法 [[Construct]] (該方法允許普通的函數通過 new 調用),也沒有 prototype 屬性。因此, new (() => {}) 會拋出錯誤。
除了那些意外,箭頭函數和普通的函數沒有明顯的區別。例如, typeof 和 instanceof 產生同樣的結果:
復制代碼
typeof () => {}
//"function"
() => {} instanceof Function
//truetypeof function () {}
//"function"
function () {} instanceof Function
//true
復制代碼
函數表達式和對象字面量是例外,這種情形下必須放在括號里面,因為它們看起來像是函數聲明和代碼塊。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100479.html
摘要:錯誤的寫法錯誤的寫法中的構造函數新增了支持默認參數和不定參數。箭頭函數的簡單理解箭頭函數的左邊表示輸入的參數,右邊表示輸出的結果。但是有了尾調用優化之后,遞歸函數的性能有了提升。 作為前端切圖仔,越發覺得自己離不開函數了。 說到JavaScript函數,腦子里都是匿名函數、普通函數、閉包函數、構造函數......然后還能說出一大堆函數的概念。如果你達到這個水平,那么函數對你來說沒有難度...
摘要:的翻譯文檔由的維護很多人說,阮老師已經有一本關于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:有傳聞說,箭頭函數的語法,是受到了的影響,并且它與中的語法一樣,共享上下文。箭頭函數是新增加的一個特性。箭頭函數沒有自己的值,其值是通過繼承其它傳入對象而獲得的通常來說是上一級外部函數的的指向。 箭頭函數 1. 簡單的定義: 胖箭頭函數 Fat arrow functions,又稱箭頭函數,是一個來自ECMAScript 2015(又稱ES6)的全新特性。有傳聞說,箭頭函數的語法=>,...
摘要:但是有了尾調用優化之后,遞歸函數的性能有了提升。常被用來檢查對象中是否存在某個鍵名,集合常被用來獲取已存的信息。循環解構對象本身不支持迭代,但是我們可以自己添加一個生成器,返回一個,的迭代器,然后使用循環解構和。 一、let和const 在JavaScript中咱們以前主要用關鍵var來定義變量,ES6之后,新增了定義變量的兩個關鍵字,分別是let和const。對于變量來說,在ES5中...
閱讀 3652·2021-09-02 15:11
閱讀 4563·2021-08-16 10:47
閱讀 1559·2019-08-29 18:35
閱讀 3030·2019-08-28 17:54
閱讀 2841·2019-08-26 11:37
閱讀 1495·2019-08-23 16:51
閱讀 1797·2019-08-23 14:36
閱讀 1800·2019-08-23 14:21