參數(shù)默認(rèn)值: 如果沒有傳參數(shù)就相當(dāng)于傳的是 undefined, 不能是 null, 因?yàn)闀?huì)被解構(gòu)為 0
function sum(a, b = 2, c = 3) {
return a + b + c;
}
sum(11); // 16 , 這就相當(dāng)于sum(11, undefined, undefiend), 但是必須是undefined,他才給你解析為默認(rèn)值憎茂, 不然傳null的話 (sum(11, null, null) = 11)珍语,它會(huì)給你解析為0
面試題
function test() {
console.log("abc");
return document.getElementsByClassName("container")[0];
}
function createEle(ele = "div", container = test(), content = "何難勛最帥") {
const el = document.createElement(ele);
if (content) {
el.innerText = content;
}
container.appendChild(el);
}
// 打印兩次, 因?yàn)榍懊鎯纱味紓鞯氖莡ndefined, 所以使用默認(rèn)值竖幔,執(zhí)行test()板乙,第三次傳了值,就用傳入的值拳氢,不執(zhí)行test
createEle(undefined, undefined, undefined);
createEle(undefined, undefined, "何難勛");
createEle(undefined, document.querySelector(".wrapper"));
擴(kuò)展
- 參數(shù)對(duì)于在嚴(yán)格模式下不一樣亡驰,傳參進(jìn)來,如果在非嚴(yán)格模式下饿幅,你在函數(shù)里面修改了值凡辱,它的 arguments 里面的值也會(huì)變淌山,但是在嚴(yán)格模式下揖闸,他們兩個(gè)是脫離的盈简,你定義的值缔俄,arguments 里面的值不會(huì)變
注意點(diǎn): 如果設(shè)置了默認(rèn)值埃篓,該函數(shù)會(huì)自動(dòng)變?yōu)樵趪?yán)格模式下執(zhí)行歉眷,arguments 和形參脫離袱蜡, 所以盡量不要使用 arguments叙淌,因?yàn)榭赡軙?huì)造成一些問題
function test (a, b) {
console.log(arguments[0], arguments[1]) // 1, 2
a = 3
console.log(arguments[0], arguments[1]) // 3, 2
console.log(a, b) // 3,2
}
test(1,2)
'use strict' ------------嚴(yán)格模式下
function test (a, b) {
console.log(arguments[0], arguments[1]) // 1, 2
a = 3
console.log(arguments[0], arguments[1]) // 1 , 2 : 在嚴(yán)格模式下市咆,arguments的值不變
console.log(a, b) // 3,2
}
test(1,2)
- 留意暫時(shí)性死區(qū)
- 形參和 ES6 中的 let 和 const 聲明一樣汉操,具有作用域,并且根據(jù)參數(shù)的聲明順序存在暫時(shí)性死區(qū)
function test(a, b = a) {
console.log(a, b);
}
test(1, 2); // 1, 2 ; 因?yàn)槎紓魅肓酥得衫迹圆粫?huì)使用默認(rèn)值
test(1); // 1, 1 ; 因?yàn)閍已經(jīng)被定義為1了磷瘤,所以執(zhí)行到b的時(shí)候,能拿到a的值
function test(a = b, b) {
console.log(a, b);
}
test(1, 2); // 1, 2 ; 因?yàn)槎紓魅肓酥邓驯洌圆粫?huì)使用默認(rèn)值
test(1); // 報(bào)錯(cuò)采缚,會(huì)說b還沒初始化就被調(diào)用
注意: let 在函數(shù)內(nèi)部定義變量,不能和形參同名挠他,否則會(huì)報(bào)錯(cuò)
剩余函數(shù): ES6 的剩余參數(shù)專門用于收集末尾的所有參數(shù)扳抽,將其放置到一個(gè)形參數(shù)組中;
解決的問題:
剩余參數(shù):
解決問題:
- arguments:
1. 如果和形參配合使用殖侵,容易導(dǎo)致混亂贸呢,eg:在形參沒有設(shè)置默認(rèn)值的情況下,在函數(shù)里面修改了形參的值之后拢军,arguments里面的值也會(huì)變楞陷; 但是設(shè)置了默認(rèn)值之后,函數(shù)就自動(dòng)變?yōu)榱?嚴(yán)格模式',形參和實(shí)參就會(huì)相互脫離朴沿,你修改值不會(huì)改變arguments的值
2. 從語義上猜谚,使用arguments獲取參數(shù)败砂,由于形參缺失,無法從函數(shù)定義上理解函數(shù)的真實(shí)意圖
- 就是寫的函數(shù)讓調(diào)用者爽魏铅,不用給它規(guī)定傳什么類型昌犹,如一般我們的方法會(huì)要求傳數(shù)組...
用來代替arguments,不僅讓調(diào)用者不用關(guān)注是什么類型,任意傳值览芳,然后就是arguments的缺陷斜姥,
// 收集參數(shù): 一定是收集最后的參數(shù)的
function test(...args) {
// args收集了所有的參數(shù),形成了一個(gè)數(shù)組
}
*細(xì)節(jié)
// 數(shù)組克隆
var arr = [...arr1]
// 對(duì)象淺克隆沧竟,沒有進(jìn)行深層次的克隆铸敏,也就是第二層對(duì)象就相同了
var obj = {...obj1}
// 對(duì)象淺克隆,沒有進(jìn)行深層次的克隆悟泵,也就是第二層對(duì)象就相同了
// eg:
var obj = { name: 'hnx', obj1: { age: 18}}
var obj2 = {...obj, name: 'xtf' }
obj1.obj1 == obj.obj1 // true , 原因是它只是展開了第一層次杈笔,而沒有展開第二層
*展開: ...
function test(a, b, c) {
console.log(a, b, c)
}
var arr = ['adf', 'af', 'affgd']
test(...arr) // 將arr展開傳入
*柯里化
function cal(a, b, c, d) {
return a + b * c - d
}
// cal(1,2, 3, 4)
// cal(1,2, 4, 5)
// cal(1,2, 6, 7)
// cal(1,2, 8, 9)
// 調(diào)用的時(shí)候前兩個(gè)參數(shù)都是一樣,那就用一個(gè)curry方法糕非,將固定的參數(shù)拿出去蒙具,返回一個(gè)新的函數(shù)執(zhí)行剩余的參數(shù)
const newCal = curry(cal, 1, 2)
console.log(newCal(3, 4)) //1 + 2 * 3 - 4
console.log(newCal(4, 5)) //1 + 2 * 4 - 5
console.log(newCal(6, 7)) //1 + 2 * 6 - 7
console.log(newCal(8, 9)) //1 + 2 * 8 - 9
const newCal2 = newCal(3)
console.log(newCal2(9)) // 1 + 2 * 3 - 9 參數(shù)不夠,那繼續(xù)返回一個(gè)函數(shù)再次執(zhí)行朽肥,直到參數(shù)傳完禁筏,才結(jié)束
// curry: 柯里化,用戶固定某個(gè)函數(shù)的前面的參數(shù)衡招,得到一個(gè)新的函數(shù)篱昔,新的函數(shù)調(diào)用時(shí),接受剩余的參數(shù)
function curry(fn, ...args) {
// console.log(args) // 是一個(gè)數(shù)組
return function (...subArgs) {
// 判斷參數(shù)是否傳完始腾,就將兩個(gè)數(shù)組加起來的長度看是否大于fn形參的長度
// 拼接的方法
// 1. const allArgs = [...args, ...subArgs]
const allArgs = args.concat(subArgs);
if (allArgs.length >= fn.length) {
// 參數(shù)夠了
return fn(...allArgs)
} else {
// 參數(shù)不夠
return curry(fn, ...allArgs)
}
}
}