破晓 发表于 2016-8-11 11:27:49

ES6笔记之参数默认值(译)

<ul style="padding-left: 30px; margin-top: 14px; margin-bottom: 14px; list-style-type: square; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><li>原文链接:<a href="http://dmitrysoshnikov.com/ecmascript/es6-notes-default-values-of-parameters/" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219); border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: transparent;">http://dmitrysoshnikov.com/</a></li><li>原文作者:Dmitry Soshnikov</li><li>译者做了少量补充</li></ul><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">在这个简短的笔记中我们聊一聊ES6的又一特性:带默认值的函数参数。正如我们即将看到的,有些较为微妙的CASE。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">ES5及以下手动处理默认值</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">在ES6默认值特性出现前,手动处理默认值有几种方式:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">message</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> level</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
level </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> level </span><span class="pun" style="color: rgb(102, 102, 0);">||</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'warning'</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">level</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">': '</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> message</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">'low memory'</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// warning: low memory</span><span class="pln" style="color: rgb(0, 0, 0);">
log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">'out of memory'</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'error'</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// error: out of memory</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">为了处理参数未传递的情况,我们常看到typeof检测:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">typeof</span><span class="pln" style="color: rgb(0, 0, 0);"> level </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'undefined'</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
level </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'warning'</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">有时也可以检查arguments.length</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">arguments</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">length </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
level </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'warning'</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这些方法都可以很好的工作,但都过于手动且缺少抽象。ES6规范了直接在函数头定义参数默认值的句法结构。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">ES6默认值:基本例子</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">默认参数特性在很多语言中普遍存在,其基本形式可能大多数开发者都比较熟悉:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">message</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> level </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'warning'</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">level</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">': '</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> message</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">'low memory'</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// warning: low memory</span><span class="pln" style="color: rgb(0, 0, 0);">
log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="str" style="color: rgb(0, 136, 0);">'out of memory'</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'error'</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// error: out of memory</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">参数默认值使用方便且毫无违和感。接下来让我们深入细节实现,扫除默认参数所带来的一些困惑。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">实现细节</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">以下为一些函数默认参数的ES6实现细节。</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">执行时求值</h4><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">相对其它一些语言(如Python)在定义时一次性对默认值求值,ECMAScript在每次函数调用的执行期才会计算默认值。这种设计是为了避免在复杂对象作为默认值使用时引发一些困惑。接下来请看下面<strong>Python</strong>的例子:</p><pre class="prettyprint lang-python prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">def</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[]):</span><span class="pln" style="color: rgb(0, 0, 0);">
x</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">append</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> x

</span><span class="com" style="color: rgb(136, 0, 0);"># 我们可以看到默认值在函数定义时只创建了一次</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);"># 并且存于函数对象的属性中</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">print</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">foo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">__defaults__</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># ([],)</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># </span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># </span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># </span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">print</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">foo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">__defaults__</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># (,)</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">为了避免这种现象,Python开发者通常把默认值定义为<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">None</code>,然后为这个值做显式检查:</p><pre class="prettyprint lang-python prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">def</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">None</span><span class="pun" style="color: rgb(102, 102, 0);">):</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="kwd" style="color: rgb(0, 0, 136);">is</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">None</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);">
    x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[]</span><span class="pln" style="color: rgb(0, 0, 0);">
x</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">append</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">print</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">print</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">foo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">__defaults__</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># (None,)</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># </span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># </span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># </span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">print</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">foo</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">__defaults__</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);"># (,)</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">就目前,很好很直观。接下来你会发现,若不了解默认值的工作方式,ES5语义上会产生一些困惑。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">外层作用域的遮蔽</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">来看下面的例子:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> x</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">y</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 2, 不是 1!</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">来上例的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">y</code>输出结果看起来像是<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">1</code>,但实际上是<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">2</code>,不是<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">1</code>。原因是参数中的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>与全局的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>不同。由于默认值在函数调用时求值,所以当赋值<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">=x</code>时,<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>已经在内部作用域决定了,引用的是参数<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>本身。也就是说,参数<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>被全局的同名变量遮蔽,所以每次默认值中访问<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>时,实际访问到的是参数中的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">参数的TDZ(Temporal Dead Zone,暂存死区)</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">ES6提到所谓的TDZ(暂存死区),意指这样的程序区域:初始化前的变量或参数不能被访问。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">考虑到对于参数,不能将自己作为默认值:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> x</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// throws!</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">...</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">赋值<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">=x</code>正如我们上面提到的那样,<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>会被解释为参数级作用域中的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>,而全局的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>会被遮蔽。但是,<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>位于TDZ,在初始化前不能被访问。因此,它不能自己初始化自己。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">注意,上面之前的例子中的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">y</code>却是合法的,因为x在之前已经初始化了(隐式的默认值<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">undefined</code>)。所以我们再看下:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> x</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// OK</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">...</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这样不会出问题,因为在ECMAScript中,参数的解析顺序是从左到右,所以在对<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">y</code>求值时<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>已经可用。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">我们提到过参数是和"内部作用域"相关的,在ES5中我们可假设这个"内部作用域"就是函数作用域。但更复杂的情况:可能是函数的作用域,或者,一个只为存储参数绑定的立即作用域。让我们继续探索。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">有条件的参数立即作用域</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">事实上,对于一些参数(至少一个)有默认值的情况,ES6会定义一个立即作用域来存储这些参数,并且这个作用域并不会与函数作用域共享。在这方面这是ES6与ES5的一个主要区别。有点晕?不要紧,看下例子你就懂。</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">3</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
y</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 局部变量`x`会被改写乎?</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// no, 依然是3, 不是2</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="com" style="color: rgb(136, 0, 0);">// 而且外层的`x`也未变化</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">在这个例子中,我们有三个作用域:全局环境、参数环境、函数环境:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"></span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">3</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 函数</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">-&gt;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">undefined</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">}}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 参数</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">-&gt;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 全局</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">现在我们应该清楚了,当作为参数的函数对象<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">y</code>执行时,它内部的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>会被就近解析(也就是上面说的参数环境),函数作用域对其并不可见。</p><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">编译到ES5</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">如果我们想把ES6代码编译到ES5,并且需要搞清楚这个立即作用域究竟是什么样的,我们可以得到像这样的东东:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="com" style="color: rgb(136, 0, 0);">// ES6</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">3</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
y</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 局部变量`x`会被改写吗?</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// no, 依然是3, 不是2</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="com" style="color: rgb(136, 0, 0);">// 编译到ES5</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">// 设置默认参数</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">typeof</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'undefined'</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
    y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 现在弄清楚了,将会更新参数中的`x`</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
    </span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">3</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 这里的`x`是函数作用域的</span><span class="pln" style="color: rgb(0, 0, 0);">
    y</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
    console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}.</span><span class="pln" style="color: rgb(0, 0, 0);">apply</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">this</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> arguments</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">参数级作用域的存在原因</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">设计参数级作用域的目的究竟是什么?为什么不能像ES5那样可以访问到函数作用域中的变量?原因:参数默认值是函数时,其函数体内的同名变量不应该影响被捕获闭包中的同名绑定。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">例:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> x</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 捕获 `x`</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 正确的应该是 1, 不是 2</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">如果我们在函数体内创建函数<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">y</code>,它内部的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">return x</code>中的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>会捕获函数作用域下的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>,也就是<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">2</code>。但是,很明显,参数<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">y</code>函数中的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>应该捕获到全局的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>,也就是<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">1</code>(除非被同名参数遮蔽)。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">同时,这里不能在外部作用域下创建函数,因为这样就意味着无法访问这个函数的参数了,所以我们应该这样做:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">y</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> z </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 现在全局`x` 和参数`y`均在参数`z`函数中可见</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">3</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> z</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 2, 不是 4</span></code></pre><h3 style="font-size: 20px; counter-reset: subsection 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">若不创建参数级作用域</h3><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">上面的描述的默认值工作方式,在语义上与最开始我们手动实现默认值完全不同,例:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">if</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">typeof</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">==</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">'undefined'</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
    y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">3</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
y</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 局部变量`x`会被改写么?</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 这次被改写了!输出2</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="com" style="color: rgb(136, 0, 0);">// 而全局的`x`仍然未变化</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">这个事实很有趣:如果函数无默认值,它不会创建这个立即作用域,并且与函数环境共享参数绑定,也就是像ES5那样处理。这也是为什么说是『有条件的参数立即作用域』</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">为什么会这样?为什么不每次创建参数级作用域?只是为了优化?非也非也。这么做的原因其实是为了向后兼容ES5:上面手动模拟默认值机制的代码应该更新函数体的<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>(也就是参数<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>,在相同作用域下实际是同一个变量被重复声明,一次是参数定义,一次是局部变量<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">x</code>)。</p><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">另外,需要注意到只有变量和函数允许重复声明,而用let/const重复声明参数是不允许的:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">5</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
let x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// error</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// error</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span></code></pre><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">undefined的检测</h2><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">另外一个有趣的事情是:是否默认值会被应用将取决于初始值也就是传参是否为<code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: normal; margin-right: 0.25em; margin-left: 0.25em; padding-right: 0.4em; padding-left: 0.4em; border: 1px solid rgb(221, 221, 221); border-radius: 3px; background-color: rgb(248, 248, 248);">undefined</code>(在进入上下文时被赋值)。例:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">();</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// undefined, 2</span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1, 2</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">undefined</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">undefined</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// undefined, 2</span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">undefined</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1, 2</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">通常情况下在一些编程语言中,带默认值参数会在必选参数的后面,但是,在JavaScript中允许下面的构造:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1, undefined</span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">undefined</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 2, 1</span></code></pre><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">解构组件的默认值</h2><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">另一个默认值涉及到的地方是解构组件的默认值。解构赋值的讨论不在本文中详述,但我们可以看一些简单的例子。对于在函数参数中使用解构的处理,与上面描述过的默认值处理相同:也就是必要时会创建两个作用域:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pln" style="color: rgb(0, 0, 0);"> foo</span><span class="pun" style="color: rgb(102, 102, 0);">({</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">5</span><span class="pun" style="color: rgb(102, 102, 0);">})</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">

foo</span><span class="pun" style="color: rgb(102, 102, 0);">({});</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// undefined, 5</span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">({</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1, 5</span><span class="pln" style="color: rgb(0, 0, 0);">
foo</span><span class="pun" style="color: rgb(102, 102, 0);">({</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1, 2</span></code></pre><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">当然,解构的默认值更加通用,不只在函数参数默认值中可用:</p><pre class="prettyprint lang-javascript prettyprinted" style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; padding: 6px 10px; border: 1px solid rgb(221, 221, 221); font-size: 12px; line-height: 18px; overflow: auto; border-radius: 3px; word-break: break-all; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><code style="font-family: consolas, monaco, menlo, &quot;courier new&quot;, courier, monospace; display: inline-block; line-height: 1.5; border: 0px none; border-radius: 0px; font-size: inherit; background: none;"><span class="kwd" style="color: rgb(0, 0, 136);">var</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">5</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
console</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">log</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// 1, 5</span></code></pre><h2 style="font-size: 26px; margin-top: 20px; margin-bottom: 20px; counter-reset: section 0; font-weight: normal; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">结论</h2><p style="margin-top: 18px; margin-bottom: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;">希望这个简短的记录能帮助大家理解ES6中的默认值特性的细节。需要注意的是,由于这个"第二作用域"是最近才加入到规范草稿中的,因此截至本文撰写时(2014年8月21日),没有任何引擎正确的实现了ES6默认值(它们全部只创建了一个作用域,也就是函数作用域)。默认值显然是一个有用的特性,它使得我们的代码更加优雅和明确。</p><h4 style="font-size: 18px; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif;">作者&amp;鸣谢</h4><ul style="padding-left: 30px; margin-top: 14px; margin-bottom: 14px; list-style-type: square; color: rgb(51, 51, 51); font-family: &quot;helvetica neue&quot;, tahoma, &quot;hiragino sans gb&quot;, stheiti, &quot;wenquanyi micro hei&quot;, 微软雅黑, 宋体, sans-serif; font-size: 16px; line-height: 27.2px;"><li>作者:<a href="http://dmitrysoshnikov.com/" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219); border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: transparent;">Dmitry Soshnikov</a></li><li>发布时间:2014年8月21日</li><li>译者:<a href="http://bosn.me/" target="_blank" style="text-decoration: none; color: rgb(49, 135, 219); border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: transparent;">Bosn</a></li><li>鸣谢:感谢@紫云妃 对术语解释上的指导和帮助</li></ul><p></p>
页: [1]
查看完整版本: ES6笔记之参数默认值(译)