函數(shù)參數(shù)的默認(rèn)值
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
function Point(x = 0, y = 0) {
this.x = x;
this.y = y;
}
var p = new Point();
p // { x: 0, y: 0 }
解構(gòu)賦值默認(rèn)值的使用:
function fetch(url, { body = '', method = 'GET', headers = {} }) {
console.log(method);
}
fetch('http://example.com', {})// "GET"
fetch('http://example.com')// 報(bào)錯(cuò)
函數(shù)的length屬性:
指定了默認(rèn)值以后,函數(shù)的length
屬性翎冲,將返回沒(méi)有指定默認(rèn)值的參數(shù)個(gè)數(shù)华畏。也就是說(shuō),指定了默認(rèn)值后跨嘉,length
屬性將失真川慌。
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
利用參數(shù)默認(rèn)值,可以指定某一個(gè)參數(shù)不得省略祠乃,如果省略就拋出一個(gè)錯(cuò)誤
function throwIfMissing() {
throw new Error('Missing parameter');
}
function foo(mustBeProvided = throwIfMissing()) {
return mustBeProvided;
}
foo()
rest參數(shù)
ES6引入rest參數(shù)(形式為“...變量名”)梦重,用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對(duì)象了亮瓷。rest參數(shù)搭配的變量是一個(gè)數(shù)組琴拧,該變量將多余的參數(shù)放入數(shù)組中。與java中的可變形參功能一樣嘱支。
// arguments變量的寫法
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
// rest參數(shù)的寫法
const sortNumbers = (...numbers) => numbers.sort();
擴(kuò)展運(yùn)算符
擴(kuò)展運(yùn)算符(spread)是三個(gè)點(diǎn)(...)艾蓝。它好比rest參數(shù)的逆運(yùn)算力崇,將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列。
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>]
// ES5的寫法
Math.max.apply(null, [14, 3, 77])
// ES6的寫法
Math.max(...[14, 3, 77])
// 等同于
Math.max(14, 3, 77);
擴(kuò)展運(yùn)算符的應(yīng)用
- 合并數(shù)組
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];
// ES5的合并數(shù)組
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6的合并數(shù)組
[...arr1, ...arr2, ...arr3
]// [ 'a', 'b', 'c', 'd', 'e' ]
-
與解構(gòu)賦值結(jié)合
擴(kuò)展運(yùn)算符可以與解構(gòu)賦值結(jié)合起來(lái)赢织,用于生成數(shù)組亮靴。
const [first, ...rest] = [1, 2, 3, 4, 5];
first
// 1
rest
// [2, 3, 4, 5]
const [first, ...rest] = [];
first
// undefined
rest
// []
const [first, ...rest] = ["foo"];
first
// "foo"
rest
// []
- 字符串
[...'hello'];
[...'hello'].reverse().join("")
-
實(shí)現(xiàn)了Iterator接口的對(duì)象
任何Iterator接口的對(duì)象,都可以用擴(kuò)展運(yùn)算符轉(zhuǎn)為真正的數(shù)組于置。
var nodeList = document.querySelectorAll('div');var array = [...nodeList];
-
Map和Set結(jié)構(gòu)茧吊,Generator函數(shù)
擴(kuò)展運(yùn)算符內(nèi)部調(diào)用的是數(shù)據(jù)結(jié)構(gòu)的Iterator接口,因此只要具有Iterator接口的對(duì)象八毯,都可以使用擴(kuò)展運(yùn)算符搓侄,比如Map結(jié)構(gòu)。
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]
var go = function*(){
yield 1;
yield 2;
yield 3;
};
[...go()]
// [1, 2, 3]
- 嚴(yán)格模式
從ES5開(kāi)始话速,函數(shù)內(nèi)部可以設(shè)定為嚴(yán)格模式讶踪。
function doSomething(a, b) {
'use strict';
// code
}
只要函數(shù)參數(shù)使用了默認(rèn)值、解構(gòu)賦值泊交、或者擴(kuò)展運(yùn)算符乳讥,那么函數(shù)內(nèi)部就不能顯式設(shè)定為嚴(yán)格模式,否則會(huì)報(bào)錯(cuò)廓俭。但可以如下解決(包含在一個(gè)立即執(zhí)行的函數(shù)里):
const doSomething = (function () {
'use strict';
return function(value = 42) {
return value;
};
}());
name屬性
函數(shù)的name屬性云石,返回該函數(shù)的函數(shù)名。箭頭函數(shù)
var f = v => v;
上面的箭頭函數(shù)等同于:
var f = function(v) { return v;};```
如果箭頭函數(shù)的代碼塊部分多于一條語(yǔ)句研乒,就要使用大括號(hào)將它們括起來(lái)汹忠,并且使用return語(yǔ)句返回。
由于大括號(hào)被解釋為代碼塊雹熬,所以如果箭頭函數(shù)直接返回一個(gè)對(duì)象宽菜,必須在對(duì)象外面加上括號(hào)。
var getTempItem = id => ({ id: id, name: "Temp" });
箭頭函數(shù)可以與變量解構(gòu)結(jié)合使用竿报。
const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}
箭頭函數(shù)的一個(gè)用處是簡(jiǎn)化回調(diào)函數(shù)铅乡。
// 正常函數(shù)寫法
[1,2,3].map(function (x) { return x * x;});
// 箭頭函數(shù)寫法
[1,2,3].map(x => x * x);
rest用法
const numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)// [1,2,3,4,5]
const headAndTail = (head, ...tail) => [head, tail];
headAndTail(1, 2, 3, 4, 5)// [1,[2,3,4,5]]
+ 使用注意點(diǎn)
箭頭函數(shù)有幾個(gè)使用注意點(diǎn)。
- 函數(shù)體內(nèi)的this對(duì)象仰楚,就是定義時(shí)所在的對(duì)象隆判,而不是使用時(shí)所在的對(duì)象。
- 不可以當(dāng)作構(gòu)造函數(shù)僧界,也就是說(shuō)侨嘀,不可以使用new命令,否則會(huì)拋出一個(gè)錯(cuò)誤捂襟。
- 不可以使用arguments對(duì)象咬腕,該對(duì)象在函數(shù)體內(nèi)不存在。如果要用葬荷,可以用Rest參數(shù)代替涨共。
- 不可以使用yield命令纽帖,因此箭頭函數(shù)不能用作Generator函數(shù)。
上面四點(diǎn)中举反,第一點(diǎn)尤其值得注意懊直。this對(duì)象的指向是可變的,但是在箭頭函數(shù)中火鼻,它是固定的室囊。
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭頭函數(shù)
setInterval(() => this.s1++, 1000);
// 普通函數(shù)
setInterval(function () {
this.s2++;
}, 1000);}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3// s2: 0
箭頭函數(shù)可以讓this指向固定化,這種特性很有利于封裝回調(diào)函數(shù)
所以魁索,箭頭函數(shù)轉(zhuǎn)成ES5的代碼如下融撞。
// ES6function foo() {
setTimeout(() => {
console.log('id:', this.id); }, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
下面是一個(gè)部署管道機(jī)制(pipeline)的例子,即前一個(gè)函數(shù)的輸出是后一個(gè)函數(shù)的輸入粗蔚。
const pipeline = (...funcs) => val => funcs.reduce((a, b) => b(a), val);
const plus1 = a => a + 1;
const mult2 = a => a * 2;
const addThenMult = pipeline(plus1, mult2);
addThenMult(5)// 12