摘要:正是因為它沒有,所以也就不能用作構造函數。不可以當作構造函數,也就是說,不可以使用命令,否則會拋出一個錯誤。不可以使用對象,該對象在函數體內不存在。
箭頭函數
在之前ES5的版本中,我們定義一個函數的形式如下:
function a() { // do something…… }
但是在ES6中,則新增了箭頭函數的方式,ES6中允許使用“箭頭”(=>)來定義函數。
() => { // do something…… }
其中()中代表的是參數部門,{}中是函數體部分。
如果箭頭函數不需要參數或者需要多個參數時,需要使用一個()來包裹,當只有一個參數時,可以省略()。
var f = () => 5; // 等同于 var f = function () { return 5 }; var sum = (num1, num2) => num1 + num2; // 等同于 var sum = function(num1, num2) { return num1 + num2; }; var f = v => v; // 等同于 var f = function (v) { return v; };
當我們在函數中返回一個對象時,之前的寫法是:
var f = function(id) { return { id: id, name: "name" } }
此時如果改為箭頭函數的方式來寫時,需要注意的是,由于在ES6中{}代表了一個代碼塊,所以在返回一個對象的時候,需要在對象{}外面使用括號包起來:
let f = id => ({id: id, name: "name"})
如果箭頭函數只有一行語句,且不需要返回值,可以采用下面的寫法,就不用寫大括號了。
let fn = () => void doesNotReturn();
不難發現,ES6中的箭頭函數相對ES5中的函數的寫法更加的簡潔方便
const isEven = n => n % 2 == 0; const square = n => n * n;
如上面只是簡單地兩行,就定義了兩個常用的工具函數。按照之前的寫法則會書寫多行。特別是在針對回調函數的時候,更能夠起到簡化的作用:
// ES5的寫法 var evens = [1,2,3,4,5]; var odds = evens.map(function(v){ return v + 1 }) // ES6的寫法 let evens = [1,2,3,4,5]; let odds = evens.map(v => v + 1)箭頭函數的this的綁定
箭頭函數和普通函數的另一個區別,在于this的綁定。例如:
var factory = function() { this.a = "a"; this.b = "b"; this.c = { a : "a+", b : function() { return this.a } } } console.log(new factory().c.b()) // "a+"
通過上面的代碼執行可以看出,得到的結果是“a+”,從而可以看出this.a指向的是c.a。有人曾總結過this的指向是該函數被調用的對象。此處b是c調用的,所以指向c中的a。現在修改為ES6的箭頭函數的寫法:
let factory = function() { this.a = "a"; this.b = "b"; this.c = { a : "a+", b : () => { return this.a } } } console.log(new factory().c.b()) // "a"
執行上面的代碼發現,輸出的結果是“a”,這又是為什么呢?請看下圖所示
箭頭函數有幾個使用注意點
(1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。這個我們在上面的例子中也已經見到過了,再舉一個比較常見的例子:
在涉及到setTimeout和setInterval時,我們之前的方法是在調用前將函數體內的this通過賦值給一個變量的方法,使得能夠在setTimeout和setInterval的回調函數中使用函數體的this
function foo() { this.id = "111"; var _this = this; setTimeout(function () { console.log("id:", _this.id); }, 100); }
但是在ES6中在使用箭頭函數之后則不再需要進行賦值替換而能直接使用函數體中的this
function foo() { this.id = "111"; setTimeout(()=>{ console.log(this.id); }, 100); }
this指向的固定化,并不是因為箭頭函數內部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this,導致內部的this就是外層代碼塊的this。正是因為它沒有this,所以也就不能用作構造函數。
除了this,以下三個變量在箭頭函數之中也是不存在的,指向外層函數的對應變量:arguments、super、new.target。
(2)不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。
(3)不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替(下面會講解rest參數)。
(4)不可以使用yield命令,因此箭頭函數不能用作 Generator 函數,這部分在后面具體遇到時再進行說明。
函數的默認參數對于帶有參數的函數,我們往往在一些情況下需要給出一個默認值的設置,當不傳入參數時,也能確保函數能夠正常執行。在ES5中,我們的寫法往往如下:
function f(x, y, z) { if(y === undefined) { y = 7; } if(z === undefined) { z = 5; } return x + y + z } console.log(f(1,3));
在ES6中允許為函數的參數設置默認值,即直接寫在參數定義的后面。
function f(x, y = 7, z = 5) { return x + y + z } console.log(f(1,3));
這段代碼和上面的執行結果是一致的,可以看出函數默認值的寫法使得函數定義更加的簡潔清晰。
ES6 的寫法還有兩個好處:
首先,閱讀代碼的人,可以立刻意識到哪些參數是可以省略的,不用查看函數體或文檔;
其次,有利于將來的代碼優化,即使未來的版本在對外接口中,徹底拿掉這個參數,也不會導致以前的代碼無法運行。
應用另外,在上面的處理中,我們并沒有針對x的賦值進行驗證,這樣當在沒有給出x的值的時候,函數會導致報錯。這個時候,我們可以來寫一個非空驗證的方法,來給函數添加校驗。
function checkParameter() { throw new Error("can"t be empty") } function f(x = checkParameter(), y = 7, z = 5) { return x + y + z } console.log(f(1,3)); try{ f() } catch(e) { console.log(e) } finally { }
這樣給x設置默認值的方式來執行校驗函數,就可以確認x的賦值的有效性了。這也是函數默認值的一種使用技巧。
rest參數上面針對參數默認值做了說明,下面我們考慮一下一個概念,可變參數,比如我們現在來做一個求和運算的函數,但是是幾個數的求和是不一定的,按照ES5中的處理,我們的寫法:
function sum() { var array = Array.prototype.slice.call(arguments); // arguments對象不是數組,而是一個類似數組的對象。所以為了使用數組的方法,必須使用Array.prototype.slice.call先將其轉為數組。 var sum = 0; array.forEach(function(item){ sum += item * 1 }) return sum; } sum(1,2,3,4)
主要是通過arguments來獲取函數的參數列表來獲取參數。但是在ES6中卻并不需要這么麻煩,ES6 引入 rest 參數(形式為...變量名),用于獲取函數的多余參數,這樣就不需要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多余的參數放入數組中。
function sum(...a) { var sum = 0; a.forEach(item => sum+= item*1) return sum; } sum(1,2,3,4)
通過ES6的rest參數,能夠更加簡潔的來實現不定參數的函數的實現。rest參數是一個真正的數組,數組特有的方法都可以使用,完全比上面通過arguments的方法更加自然、簡潔。
注:rest參數之后不能再有其他參數(即只能是最后一個參數)。
小結本次主要針對ES6中對于函數部分的相關擴展內容作了梳理,并沒有非常的全面,而是選擇其中比較常用比較重要的箭頭函數、函數默認值和rest參數這幾部分進行了說明。更加細致的體會還是需要在后續的不斷使用中進行加強和熟悉。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94174.html
摘要:前言在了解是如何編譯前,我們先看看的和的構造函數是如何對應的。這是它跟普通構造函數的一個主要區別,后者不用也可以執行。該函數的作用就是將函數數組中的方法添加到構造函數或者構造函數的原型中,最后返回這個構造函數。 前言 在了解 Babel 是如何編譯 class 前,我們先看看 ES6 的 class 和 ES5 的構造函數是如何對應的。畢竟,ES6 的 class 可以看作一個語法糖,...
摘要:由兩部分組成模板起始符,稱為沉音符反引號,其內容被識別為字符串模板。其實這是通過屬性操作中的結果,也就是說屬性將對控制符進行轉義從而實現按照普通字符輸出。的語法是緊跟在后面,兩者間不能有空格或制表符等。 1. Brief ES6(ECMAScript 6th edition)于2015年7月份發布,雖然各大瀏覽器仍未全面支持ES6,但我們可以在后端通過Node.js 0.12和io....
摘要:回顧我們先來回顧下箭頭函數的基本語法。主要區別包括沒有箭頭函數沒有,所以需要通過查找作用域鏈來確定的值。箭頭函數并沒有方法,不能被用作構造函數,如果通過的方式調用,會報錯。 回顧 我們先來回顧下箭頭函數的基本語法。 ES6 增加了箭頭函數: let func = value => value; 相當于: let func = function (value) { return ...
摘要:使用箭頭函數和構造函數當方法被調用時,會保留上下文。我們能使用這個特征用下面的方法在構造函數中重定義函數。在調用方法的方使用函數綁定語法你也可以直接在非構造函數里面的里面直接使用函數綁定。 這是React和ECMAScript6/ECMAScript7結合使用系列文章的第三篇。 下面是所有系列文章章節的鏈接: React 、 ES6 - 介紹(第一部分) React類、ES7屬性初始...
摘要:前言在閱讀入門的時候,零散的看到有私有變量的實現,所以在此總結一篇。構造函數應該只做對象初始化的事情,現在為了實現私有變量,必須包含部分方法的實現,代碼組織上略不清晰。 前言 在閱讀 《ECMAScript 6 入門》的時候,零散的看到有私有變量的實現,所以在此總結一篇。 1. 約定 實現 class Example { constructor() { this...
閱讀 1822·2023-04-26 02:32
閱讀 571·2021-11-18 13:12
閱讀 2455·2021-10-20 13:48
閱讀 2521·2021-10-14 09:43
閱讀 3832·2021-10-11 10:58
閱讀 3496·2021-09-30 10:00
閱讀 2936·2019-08-30 15:53
閱讀 3493·2019-08-30 15:53