一舔亭、 函數(shù)參數(shù)的默認值
1、基本用法
ES6
允許為函數(shù)的參數(shù)設置默認值蟀俊,直接寫在參數(shù)定義的后面分歇。
function log (t = "hello",value = "world") {
console.log(t,value)
}
log(); // => "hello world"
log('h'); // => "h world"
log("h","w"); // => "h w"
- 參數(shù)變量是默認聲明的,不能用
let
或者const
再次聲明
function foo(x = 5) {
let x = 1; // error
const x = 2; // error
}
- 使用參數(shù)默認值的時候欧漱,函數(shù)不能有同名參數(shù)
function a (x,x,y =1){
// do something
}
// 報錯
- 參數(shù)默認值不是傳值的职抡,而是每次都重新計算默認值表達式的值(惰性求值)
let x = 99;
function a (y = x +1) {
console.log(y);
}
a(); // => 100;
x = 100;
a(); // => 101
2、與結(jié)構(gòu)賦值默認值結(jié)合使用
function a({x,y=5} = {}){
console.log(x,y);
}
a(); // => undefined 5
如下:兩個函數(shù)都對參數(shù)設定了默認值误甚,區(qū)別在
- 寫法一 函數(shù)參數(shù)的默認值是空對象缚甩,但是設置了對象解構(gòu)賦值的默認值
- 寫法二 函數(shù)參數(shù)的默認值是一個有具體屬性的對象谱净,沒設置解構(gòu)賦值默認值
// 寫法一
function m1({x = 0, y = 0} = {}) {
return [x, y];
}
// 寫法二
function m2({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
// 函數(shù)沒有參數(shù)的情況
m1() // [0, 0]
m2() // [0, 0]
// x 和 y 都有值的情況
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]
// x 有值擅威,y 無值的情況
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]
// x 和 y 都無值的情況
m1({}) // [0, 0];
m2({}) // [undefined, undefined]
m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]
2李请、參數(shù)默認值的位置
- 通常情況下导盅,定義了默認值的參數(shù)白翻,應該是函數(shù)的尾參數(shù),因為這樣才比較容易看出來那些參數(shù)被省略滤馍。
3巢株、函數(shù)的length屬性
- 指定了參數(shù)默認值后阁苞,
length
屬性將失真
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
4猬错、作用域
- 一旦設置了參數(shù)的默認值茸歧,函數(shù)進行聲明初始化時显沈,參數(shù)會形成一個單獨的作用域涤浇,等到初始化結(jié)束這個作用域就會消失只锭,這種語法行為蜻展,在不設置參數(shù)默認值時纵顾,是不會出現(xiàn)的施逾。
var x = 1;
function f(x, y = x) {
console.log(y);
}
f(2); // => 2
上面代碼中曹仗,參數(shù)y
的默認值等于變量x
整葡,調(diào)用函數(shù)f
時遭居,參數(shù)形成一個單獨的作用域俱萍,在這個作用域里,默認值變量x
指向第一個參數(shù)x
岳颇,而不是全局變量x
话侧,所以輸出2
瞻鹏。
5、應用
- 利用參數(shù)默認值,可以指定某一參數(shù)不得省略盐数,省略就拋出錯誤
function throwIfMissing() {
throw new Error('Missing parameter');
}
function foo(mustBeProvided = throwIfMissing()) {
return mustBeProvided;
}
foo()
// Error: Missing parameter
二、rest參數(shù)
ES6
引入rest參數(shù)(形式為...變量名
),用來獲取函數(shù)的多余參數(shù)粤策,這樣就不需要使用arguments
對象了
- rest參數(shù)搭配的變量是一個數(shù)組,該變量將多余的參數(shù)放入數(shù)組中
function add(...values){
console.log(values); // => [2,3,5]
}
add(2,3,5);
- rest參數(shù)之后不能再有其他參數(shù)柔吼,否則會報錯
// 報錯
function f(a, ...b, c) {
// ...
}
- 函數(shù)的
length
屬性愈魏,不包括rest參數(shù)
(function(...a) {}).length // 0
(function(a, ...b) {}).length // 1
三培漏、箭頭函數(shù)
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
- 如果箭頭函數(shù)不需要參數(shù)或需要多個參數(shù)牌柄,就使用一個圓括號代表參數(shù)部分珊佣。
var f = () => 5;
var sum = (num1, num2) => num1 + num2;
- 如果箭頭函數(shù)的代碼塊部分多余一條語句咒锻,就要使用大括號將它們括起來,并使用
return
語句返回敦捧。
var sum = (num1, num2) => { return num1 + num2; }
- 由于大括號被解釋為代碼塊,所以如果箭頭函數(shù)直接返回一個對象绪颖,必須在對象外面加上括號柠横,否則會報錯晨继。
// 報錯
let getTempItem = id => { id: id, name: "Temp" };
// 不報錯
let getTempItem = id => ({ id: id, name: "Temp" });
- 箭頭函數(shù)可以與變量結(jié)構(gòu)結(jié)合使用
const full = ({ first, last }) => first + ' ' + last;
// 等同于
function full(person) {
return person.first + ' ' + person.last;
}
- 箭頭函數(shù)的一個用處是簡化回調(diào)函數(shù)。
// 正常函數(shù)寫法
[1,2,3].map(function (x) {
return x * x;
});
// 箭頭函數(shù)寫法
[1,2,3].map(x => x * x);
箭頭函數(shù)使用注意點:
1餐屎、函數(shù)體內(nèi)的this
對象,就是定義時所在的對象藏鹊,而不是使用時所在對象
2伙判、不可當構(gòu)造函數(shù)宴抚,也就是說,不可以使用new
命令
3常潮、不可以使用arguments
對象喊式,該對象在函數(shù)體內(nèi)部存在岔留,用rest參數(shù)代替
4检柬、不可使用yield
命令进胯,因此箭頭函數(shù)不能做Generator
函數(shù)
四、尾調(diào)用
尾調(diào)用是函數(shù)式編程的一個重要概念原押,指某個函數(shù)的最后一步是調(diào)用另一個函數(shù)
function f(x){
return g(x);
}
五胁镐、柯里化
函數(shù)式編程有一個概念,叫做柯里化诸衔,意思是將多參數(shù)的函數(shù)轉(zhuǎn)換成單參數(shù)的形式
function currying(fn,n){
return function(m){
return fn.call(this,m,n); // 調(diào)用傳入函數(shù)本身希停,并傳入值 n 相當于默認值
}
}
function tail(m,n){
console.log("n",n);
console.log("m",m);
}
var f = currying(tail,1); // 傳入函數(shù),指定默認值
f(5);
// => "n" 1
// => "m" 5
- 其實可以采取
ES6
的函數(shù)默認值
function tail(m,n = 1){
console.log("n",n);
console.log("m",m);
}
tail(5);
// => "n" 1
// => "m" 5