竟然修改形参有这么可怕的后果!!
今天在知乎上https://www.zhihu.com/question/24692840/answer/345252713看到为默认形参的处理办法:
function fun(name){ name=name||'join'; }
如果调用这个函数时没有传入实参,则name就是undefined,这样name就会被赋 'join' 这个值,这样不久皆大欢喜了吗?
事实是没你想的那么简单:这样做带来的副作用是会修改arguments对象(别忘了形参(parameter)和arguments对象是蜜汁同步的),当你修改形参时像ESLint等代码检查工具都会检测出来https://eslint.org/docs/rules/no-param-reassign,来看修改形参会带来什么后果:
function foo(a,b,c){ if(arguments.length<=3){ a='green'; b=arguments[0]; c=b; } return { name:a, age:b, job:c }; } console.log(foo('linwei',20,'student')); // {name:"green",age:"green",job:"green"}
你看,本来要输出
{name:"linwei",age:20,job:"student"}
结果输出了截然不同的结果。
那怎么算一个比较好的解决方案呢?来看Babel是怎么处理的:
function fn(){ var a=arguments.length>0&&arguments[0]!==undefined?arguments[0]:0; }
它干脆将值赋给一个新声明的局部变量,这样不就可以摆脱这种蜜汁同步吗?个人感觉这算比较好的解决方案了。