在使用 ES6 箭头函数时,有时会遇到使用默认参数时出现的 bug。具体来说,当使用一个默认参数后,箭头函数无法正确处理传递给它的参数。
这时候怎么办呢?我们本文将详细介绍这个 bug,以及如何解决它。
什么是 ES6 箭头函数中的默认参数 Bug?
ES6 引入了一种新的函数语法:箭头函数。使用箭头函数时,可以使用默认参数来为函数的参数添加默认值。
例如:
const sayHello = (name = 'world') => { console.log(`Hello, ${name}!`); }
在调用这个函数时,可以不传递参数:
sayHello(); // 输出 'Hello, world!'
这个默认参数的功能看起来很好用。但是,在某些情况下,使用默认参数的箭头函数却会出现 bug。
例如,假设我们有一个类:
-- -------------------- ---- ------- ----- ------- - ----------------- - -- - ---------- - ------ - ----------- - ------------- - ---------- - ------ ----------- - -
这个类的构造函数使用一个默认参数,以便在没有传递参数时,可以默认创建一个计数器。
然后我们创建一个数组,包含一些计数器实例:
const counters = [ new Counter(), new Counter(), new Counter(), ];
接下来,我们可以使用 Array.prototype.map
方法,为每个计数器实例创建一个函数,使得调用该函数会将计数器的值加一:
const addOne = () => counter => counter.increment(); const incrementCounters = counters.map(addOne());
现在,我们期望调用 incrementCounters
数组中的任何函数都会将相关计数器的值加一:
incrementCounters[0](); incrementCounters[1](); incrementCounters[2]();
但是,事实上,这个操作并没有生效!所有的计数器的值仍然为零。
我们该怎么办呢?
如何解决 ES6 箭头函数中的默认参数 Bug?
要解决这个问题,我们需要理解 JavaScript 中的 this
关键字。
在 ES6 箭头函数中,this
的指向是词法作用域,而不是函数执行时的上下文。这意味着,如果在箭头函数中调用 this
,它会指向函数外部的作用域。
然而,如果我们使用默认参数,会影响 this
指向的对象。
例如,我们将上面的计数器示例改写为使用函数表达式:
-- -------------------- ---- ------- -------- ------------- - -- - ---------- - ------ -------------- - ---------- - ------------------ ------------- -- ------------- - ---------- - ------ ----------- -- -
然后再将 addOne
函数改为函数表达式:
const addOne = function() { return function(counter) { counter.increment(); }; };
这样, 大家可以注意到 addOne 函数返回的是一个新的函数,而不是一个箭头函数。
现在,我们再使用 Array.prototype.map
方法创建一个新的函数数组:
const incrementCounters = counters.map(addOne());
现在我们再次执行这个新的数组中的函数:
incrementCounters[0](); incrementCounters[1](); incrementCounters[2]();
这一次,计数器的值都会加一!
这是因为,使用函数表达式而不是箭头函数,可以避免这个 bug 的出现。
总结
在本文中,我们学习了在使用 ES6 箭头函数时,当使用默认参数来为函数的参数添加默认值时,可能会出现的 bug。
这个问题的解决方案是,避免使用箭头函数,而改用函数表达式。
希望这篇文章可以帮助你更好地理解 ES6 箭头函数和默认参数,并且可以解决你可能会遇到的这个 bug。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64a2f0d148841e9894f6266c