![c59fff858e5f405cb5d982caa6952395.png](https://i-blog.csdnimg.cn/blog_migrate/f8ceefe900187324207222a76a452adf.jpeg)
首先,在ES6之前,我们无法给JS函数的参数设置默认值。只能通过一些变通的手段来实现,比如:
function sum(a, b) {
if (!a) {
a = 1;
}
if (!b) {
b = 2;
}
return a + b;
}
console.log(sum()); // 3
console.log(sum(2)); // 4
再比如:
function sum(a, b) {
a = a || 1;
b = b || 2;
return a + b;
}
console.log(sum()); // 3
console.log(sum(3, 4)); // 7
而随着ES6的普及,前端开发者逐渐习惯新的设置方式:
function sum(a = 1, b = 2) {
return a + b;
}
甚至更简洁的写法:
const sum = (a = 1, b = 2) => a + b;
console.log(sum()); // 3
console.log(sum(5)); // 7
看起来,不管是写法上还是代码量上都比以前优雅了许多。然而,却也存在一点点小风险。稍微修改一下函数的默认值,以及函数体处理逻辑:
const getStringLength = (str = '') => str.length;
console.log(getStringLength()); // 0
console.log(getStringLength('a')); // 1
现在看起来还是一切正常,但是,当我试着执行getStringLength(null)
的时候,浏览器却抛出了Uncaught TypeError: Cannot read property 'length' of null
的错误。从错误信息可以看出,当实参传入null
的时候,参数的值并不会使用默认值代替。
因此,当我们在实际使用中,特别是涉及从服务端取数后使用JS函数处理返回数据的场景时,使用ES6的参数默认值需要谨慎一些。举个实际的例子:假设我们有个业务是从服务端获取某条记录的评论(可以为空),由前端来判断内容中是否包含某些特殊字符(如,<
、>
等),与服务端约定数据格式如下:
{
success: true,
data: {
comment: "内容"
}
}
前端处理函数如下:
const hasSpecialChar = ({ comment = '' }) => !!comment.match(/<|>/);
// 当返回有评论的内容时
console.log(hasSpecialChar({comment: '评论<script>alert(123);</script>'})); // true
// 当返回没有评论时
console.log(hasSpecialChar({comment: null})); // Uncaught TypeError: Cannot read property 'match' of null
这样,我们的程序就不够健壮。当然,这个问题我们也可以通过让服务端不返回null
值来解决。