摘要:編程中經常定義一些短小的匿名函數,使用箭頭函數語法可使得這類函數的定義更加簡潔。外部函數的,等價于定義個局部變量修改內部的所以這樣,,也就無法修改箭頭函數的值的。拋異常即箭頭函數不能作為構造函數,其也不具有屬性。
一、概述
箭頭函數是指通過=>語法定義的函數。JS編程中經常定義一些短小的匿名函數,使用箭頭函數語法可使得這類函數的定義更加簡潔。
// ES3/5方式 var fun1 = function(x, y) { return x + y; } var arr1 = [1,2,3].map(function(item){ return item * item; }) // 箭頭函數方式 var fun2 = (x, y) => x + y; var arr2 = [1,2,3].map((item) => item * item)
少些了不少代碼,看著也簡潔許多,有木有。
二、語法
一般的語法格式:
(param1, param2, …, paramN) => { 語句 }
注意參數部分和箭頭=>之間不能換行,如:
// 正確 var add1 = (x, y) => x + y; // 正確 var add2 = (x, y) => x + y; // 正確(=>后面不會自動插入分號的) var add3 = (x, y) => x + y; // 語法錯誤 Uncaught SyntaxError: Unexpected token => var add4 = (x, y) => x + y; // 語法錯誤 Uncaught SyntaxError: Unexpected token => var add5= x => x + 2;
上例中add4定義會報錯,原因在解析的時候(x, y)后面會自動插入分號,所以當解析=>時就報錯了。
如果花括號里只包含一個return語句,則可以簡寫為:
(param1, param2, …, paramN) => 表達式 // 等價于 => { return 表達式; }
因為對象字面量也是用花括號表示的,所以當表達式是個對象字面量時需要用括號包住:
var a = p => ({a: p}) // 不能寫成:p => {a: p}
如果有且只有一個形參,則可以省略括號,簡寫為:
param => {語句} // 等價于 (param) => {語句}
如上例中的fun1定義:
var fun1 = (x, y) => x + y; // 等價于 var fun1 = (x, y) => { return x + y; }三、特性
箭頭函數不僅僅更方便定義匿名函數,它還具有一些特性,這些使得箭頭函數在使用上也更方便。
箭頭函數一般定義在一個函數內部,箭頭函數的函數體內是可以訪問外部函數定義的局部變量的(閉包),但是外部函數還有兩個特殊的變量:this和arguments。因為每個函數都具有自己的this和arguments變量,所以當內部函數訪問外部函數這兩個變量時,我們一般采用這種方式:
var outer = { name: "outer", say: function() { var _arguments = arguments, // 先把arguments賦值給局部變量_arguments _this = this; // 先把this賦值給局部變量_this function inner() { console.log(arguments.length); // 內部函數的arguments console.log(_arguments.length); // 通過局部變量_arguments訪問外部函數的arguments變量 console.log(this.name); // 內部函數的this console.log(_this.name); // 通過局部變量_this訪問外部函數的this變量 } return inner; } }
但是箭頭函數體可以直接訪問外部函數的this和arguments變量!!!逆天啊。
3.1 箭頭函數“不具有自己的this變量” 1 特性語法箭頭函數體內this變量指向外部函數的this。如上例可以寫為:
var outer = { name: "outer", say: function() { return () => { console.log(this.name); } // 外部函數outer的this, } }
并且通過call,apply,bind函數也是無法修改箭頭函數的this變量的。
var outer = { name: "outer", say: function() { var inner = () => { console.log(this.name); } // 依舊外部函數outer的this, return inner.bind({name: "inner"}) // } }2 特性原理
箭頭函數并不是真的不具有自己的this變量,只是它重新修改this變量的值。
var outer = { name: "outer", say: function() { return () => { console.log(this.name); } // 外部函數outer的this, } } // 等價于: var outer = { name: "outer", say: function say() { var _this = this; // 定義個局部變量_this return function () { this = _this; // 修改內部的this console.log(this.name); }; } };
所以這樣call,apply,bind也就無法修改箭頭函數的this值的。
3.2 箭頭函數“不具有自己的arguments變量”跟this變量類似箭頭函數也“不具有自己的arguments變量”,原理跟this類似。
總結一句話:箭頭函數是為了特殊的使用場景(即更方便的定義和使用匿名函數),它的這些特性也是為了方便其使用。
四、使用限制 4.1 不能用new 操作符對箭頭函數使用new操作符會拋TypeError異常。
var A = () => {} var a = new A(); //拋異常 Uncaught TypeError: A is not a constructor
即箭頭函數不能作為構造函數,其也不具有prototype屬性。原因應該是其內部的this變量被重寫了,不能作為構造函數理所當然。但是箭頭函數也是函數:
var a = () => {}; console.log(a instanceof Function); // true
總結一句話:箭頭函數是不能作為構造函數的特殊函數。
4.2 跟其他運算符一起用箭頭函數=>不是運算符,當箭頭函數作為右值跟其他運算符一起運算操作時其具有特殊的解析順序
function func(callback) { // 一般函數方式 callback = callback || function() {} // 沒問題 // 報錯了,語法錯誤:Uncaught SyntaxError: Unexpected token ) callback = callback || () => {}; // 這樣寫就對了 callback = callback || (() => {}); }
總結一句話:箭頭函數雖然不是運算符,但其寫法和解析有點像運算符的操作。當箭頭函數作為右值參與其他運算符的運算時記得加上括號。
4.3 需要使用自己this的函數箭頭函數"沒有自己的this",所以它不適用那些需要使用自己this的場景(如成員方法,事件回調函數等)
// 成員方法 var outer = { name: "outer", say: () => { // 這里的this不是outer,但是我們期望在成員方法的this應該指向對象本身 console.log(this.name); } } // 事件處理函數 document.getElementById("test").onclick = function() { console.log(this); // 這里的this不是觸發事件的DOM對象 }
總結一句話:箭頭函數雖然寫起了比較爽,但不能濫用,它是有特殊應用場景的。要懂得什么時候不該用。
參考MDN 箭頭函數
w3cPlus ES6學習筆記:箭頭函數
JavaScript 語句后應該加分號么?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96284.html
摘要:也就是說箭頭函數的的值不再根據調用時上下文確定,而是像普通變量那樣根據定義時的作用域鏈進行查找。箭頭函數中的依然要根據定義時的作用域鏈進行查找。知乎這篇文章對箭頭函數的一些不適合的場景進行了總結,可以作為參考。 es6 - 箭頭函數 哇,箭頭函數...,聽起來好NB,但是如果你知道它是因為使用了=>這樣類似箭頭的符號 ,所以才叫箭頭函數。 瞬間感覺:呵,這名字起的...。 es6增加了...
摘要:特性介紹箭頭函數是新增的特性之一,它為這門語言提供了一種全新的書寫函數的語法。用生成的函數會定義一個自己的,而箭頭函數沒有自己的,而是會和上一層的作用域共享。 本文同步自我得博客:http://www.joeray61.com JS中的箭頭 箭頭在JS里并不算是個新鮮的玩意兒,一直以來,JS都支持-->這樣的箭頭。 很早的時候有些瀏覽器還不支持JS,當時的人們為了兼容這些瀏覽器,需要這...
摘要:令人震驚的箭頭函數引入了寫入函數的新語法。使用箭頭函數創建簡單對象時有一個警告。代碼因此被默默地解釋為一個不執行任何操作并返回未定義的箭頭函數。內部函數是一個箭頭函數,所以它從封閉范圍繼承此函數。 箭頭從一開始就一直是JavaScript的一部分。第一個JavaScript教程建議在HTML注釋中包裝內聯腳本。這會阻止不支持JS的瀏覽器錯誤地將JS代碼顯示為文本。你會寫這樣的東西: ...
摘要:有傳聞說,箭頭函數的語法,是受到了的影響,并且它與中的語法一樣,共享上下文。箭頭函數是新增加的一個特性。箭頭函數沒有自己的值,其值是通過繼承其它傳入對象而獲得的通常來說是上一級外部函數的的指向。 箭頭函數 1. 簡單的定義: 胖箭頭函數 Fat arrow functions,又稱箭頭函數,是一個來自ECMAScript 2015(又稱ES6)的全新特性。有傳聞說,箭頭函數的語法=>,...
摘要:箭頭函數簡單的定義胖箭頭函數,又稱箭頭函數,是一個來自又稱的全新特性。箭頭函數是新增加的一個特性。使用箭頭函數的注意點箭頭函數在參數和箭頭之間不能換行。值得注意的一點就是對象的指向是可變的,但在箭頭函數內是固定的。 箭頭函數 1. 簡單的定義: 胖箭頭函數 Fat arrow functions,又稱箭頭函數,是一個來自ECMAScript 2015(又稱ES6)的全新特性。有傳聞說,...
摘要:對象的指向是可變的,但是在箭頭函數中,它是固定的。同樣的由于箭頭函數沒有自己的所以傳統的顯性綁定無效內部的指向外部在的學習中,的指向問題一直是個難點,特別是在對象方法中使用時,必須更加小心。由此箭頭函數在很大程度上減少了我們的困擾。 什么是箭頭函數 用法 ES6 允許使用箭頭(=>)定義函數 測試 var p1 = document.getElementById(test1)...
閱讀 2825·2023-04-25 20:06
閱讀 1446·2021-08-26 14:15
閱讀 2233·2021-08-12 13:27
閱讀 1771·2019-08-30 15:55
閱讀 3468·2019-08-30 13:20
閱讀 2825·2019-08-29 15:12
閱讀 3329·2019-08-29 15:06
閱讀 2858·2019-08-29 14:13