1. 形参初始化

# 1. 形参初始化

很多语言都是支持设置函数参数的默认值的,但是js在ES6 之前,不能直接为函数的参数指定默认值,只能这样做

function log(x, y) {
	if (typeof y === 'undefined') {
  		y = 'World';
	}
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China

ES6 允许直接为函数的参数设置默认值,即直接写在参数定义的后面

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值

# 2. 与解构赋值结合使用

设置默认参数,这样如果对象没有传参数,有默认值

function connect({host="127.0.0.1", username, password, port}){
	console.log(host);
	console.log(username);
	console.log(password);
	console.log(port);
}
// 调用函数
connect({
	host:'localhost',
	username: 'root',
	password: 'root',
	port: 3306
})

# 3. 对arguments的影响

在使用默认参数时,arguments对象的值不反映参数的默认值,只反映传给函数的参数。修改命名参数也不会影响arguments对象,始终以调用函数传入的参数为准

function makeKing(name = 'yk'){
	name = 'YK菌'; // 不会影响arguments对象,始终以调用函数传入的参数为准
	return `King ${arguments[0]}`;
}
console.log(makeKing());  // King undefined
console.log(makeKing('YKYK')); // King YKYK

# 4. 默认参数作用域与暂时性死区

给多个参数定义默认值实际上跟使用let关键字顺序声明变量一样

function makeKing(name='YK菌', numerals='VI'){
	return `King ${name} ${numerals}`;
}
console.log(makeKing()); // King YK菌 VI

因为是按顺序初始化的,所有可以把想想成以下的代码过程

function makeKing(){
	let name = 'YK菌';
	let numerals = 'VI';
	return `King ${name} ${numerals}`;
}
console.log(makeKing()); // King YK菌 VI

因为参数是按顺序初始化的,所以后定义的默认值参数可以引用先定义的参数

function makeKing(name='YK菌', numerals=name){
	return `King ${name} ${numerals}`;
}
console.log(makeKing()); // King YK菌 YK菌

参数初始化顺序遵循“暂时性死区”规则,即

前面定义的参数不能引用后面定义的

参数存在于自己的作用域中,不能引用函数体的作用域

# 参考资料

  1. 尚硅谷ES6教程 (opens new window) https://www.bilibili.com/video/BV1uK411H7on?p=11
  2. 阮一峰ES6教程 (opens new window) https://es6.ruanyifeng.com/#docs/function
  3. JavaScript高级程序设计(第四版) (opens new window) P293-295 https://www.ituring.com.cn/book/2472
上次更新: 2022/4/21 22:21:34