[1]參數預設值 [2]rest參數 [3]擴展運算符 [4]箭頭函數 ...
×
目錄
[1]參數預設值 [2]rest參數 [3]擴展運算符[4]箭頭函數前面的話
ES6標準關於函數擴展部分,主要涉及以下四個方面:參數預設值、rest參數、擴展運算符和箭頭函數
參數預設值
一般地,為參數設置預設值需進行如下設置
function log(x, y) { y = y || 'World'; console.log(x, y); }
但這樣設置實際上是有問題的,如果y的值本身是假值(包括false、undefined、null、''、0、-0、NaN),則無法取得本身值
function log(x, y) { y = y || 'World'; console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', NaN) // Hello World
ES6允許為函數的參數設置預設值,即直接寫在參數定義的後面
function log(x, y = 'World') { console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', NaN) // Hello NaN
[註意]參數變數是預設聲明的,所以不能用let或const再次聲明
function foo(x = 5) { let x = 1; //SyntaxError: Identifier 'x' has already been declared const x = 2; //SyntaxError: Identifier 'x' has already been declared }
尾參數
通常情況下,定義了預設值的參數,應該是函數的尾參數。因為這樣比較容易看出來,到底省略了哪些參數。如果非尾部的參數設置預設值,實際上這個參數是沒法省略的
function f(x = 1, y) { return [x, y]; } f() // [1, undefined] f(2) // [2, undefined]) f(, 1) // 報錯 f(undefined, 1) // [1, 1]
如果傳入undefined,將觸發該參數等於預設值,null則沒有這個效果
function foo(x = 5, y = 6) { console.log(x, y); } foo(undefined, null)// 5 null
length
指定了預設值以後,函數的length屬性,將返回沒有指定預設值的參數個數
(function (a) {}).length // 1 (function (a = 5) {}).length // 0 (function (a, b, c = 5) {}).length // 2
[註意]如果設置了預設值的參數不是尾參數,那麼length屬性也不再計入後面的參數了
(function (a = 0, b, c) {}).length // 0 (function (a, b = 1, c) {}).length // 1
作用域
【1】如果參數預設值是一個變數,則該變數所處的作用域,與其他變數的作用域規則是一樣的,即先是當前函數的作用域,然後才是全局作用域
var x = 1; function f(x, y = x) { console.log(y); } f(2) // 2
【2】如果函數調用時,函數作用域內部的變數x沒有生成,則x指向全局變數
var x = 1; function f(y = x) { var x = 2; console.log(y); } f() // 1
應用
利用參數預設值,可以指定某一個參數不得省略,如果省略就拋出一個錯誤
function throwIfMissing() { throw new Error('Missing parameter'); } function foo(mustBeProvided = throwIfMissing()) { return mustBeProvided; } foo()// Error: Missing parameter
[註意]將參數預設值設為undefined,表明這個參數可以省略
function foo(optional = undefined) { //todo }
rest參數
ES6引入rest參數(形式為“...變數名”),用於獲取函數的多餘參數,這樣就不需要使用arguments對象了。rest參數搭配的變數是一個數組,該變數將多餘的參數放入數組中
function add(...values) { var sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) //10
rest參數中的變數代表一個數組,所以數組特有的方法都可以用於這個變數
下麵是一個利用rest參數改寫數組push方法的例子
function push(array, ...items) { items.forEach(function(item) { array.push(item); console.log(item); }); } var a = []; push(a, 1, 2, 3);
函數的length屬性不包括rest參數
(function(a) {}).length // 1 (function(...a) {}).length // 0 (function(a, ...b) {}).length // 1
[註意]rest參數之後不能再有其他參數
//Uncaught SyntaxError: Rest parameter must be last formal parameter function f(a, ...b, c) { //todo }
擴展運算符
擴展運算符(spread)是三個點(...)。它好比rest參數的逆運算,將一個數組轉為用逗號分隔的參數序列
console.log(...[1, 2, 3])// 1 2 3 console.log(1, ...[2, 3, 4], 5)// 1 2 3 4 5 [...document.querySelectorAll('div')]// [<div>, <div>, <div>]
該運算符主要用於函數調用
function add(x, y) { return x + y; } var numbers = [4, 38]; add(...numbers) // 42
Math.max方法簡化
// ES5 Math.max.apply(null, [14, 3, 77]) // ES6 Math.max(...[14, 3, 77]) //等同於 Math.max(14, 3, 77)
push方法簡化
// ES5 var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; Array.prototype.push.apply(arr1, arr2); // ES6 var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; arr1.push(...arr2);
擴展運算符可以將字元串轉為真正的數組
[...'hello']// [ "h", "e", "l", "l", "o" ]
箭頭函數
關於箭頭函數的詳細介紹移步至此
參考資料
《ECMAScript 6入門》 阮一峰