<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Scope &amp; Closures on Xinyu's Blog</title><link>https://xinyuli.blog/zh/categories/scope--closures/</link><description>Recent content in Scope &amp; Closures on Xinyu's Blog</description><image><title>Xinyu's Blog</title><url>https://xinyuli.blog/og.png</url><link>https://xinyuli.blog/og.png</link></image><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Thu, 22 Dec 2016 08:00:00 +0800</lastBuildDate><atom:link href="https://xinyuli.blog/zh/categories/scope--closures/index.xml" rel="self" type="application/rss+xml"/><item><title>第五章作用域闭包</title><link>https://xinyuli.blog/zh/2016/12/22/%E7%AC%AC%E4%BA%94%E7%AB%A0%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%97%AD%E5%8C%85/</link><pubDate>Thu, 22 Dec 2016 08:00:00 +0800</pubDate><guid>https://xinyuli.blog/zh/2016/12/22/%E7%AC%AC%E4%BA%94%E7%AB%A0%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%97%AD%E5%8C%85/</guid><description>&lt;h2 id="实质问题-闭包的定义"&gt;实质问题, 闭包的定义&lt;/h2&gt;
&lt;p&gt;当函数访问并记住所在的词法作用域时，就产生了闭包，即使函数是在当前词法作用域之外执行。&lt;/p&gt;
&lt;p&gt;(个人理解)闭包并没有什么神奇的，闭包是词法作用域的特性，函数能够保存它本身的词法作用域的变量是肯定的，
即使这个函数嵌套在另一个函数里面也不例外。&lt;/p&gt;
&lt;h2 id="循环和闭包"&gt;循环和闭包&lt;/h2&gt;
&lt;p&gt;闭包用来保存循环变量的值，每一次循环都创建一个副本。
如下代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{})(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="模块"&gt;模块&lt;/h2&gt;
&lt;p&gt;可以利用闭包去构建模块，封装私有属性和方法，然后暴露给外部方案修改内部的属性。&lt;/p&gt;</description></item><item><title>第四章提升</title><link>https://xinyuli.blog/zh/2016/12/21/%E7%AC%AC%E5%9B%9B%E7%AB%A0%E6%8F%90%E5%8D%87/</link><pubDate>Wed, 21 Dec 2016 15:00:00 +0800</pubDate><guid>https://xinyuli.blog/zh/2016/12/21/%E7%AC%AC%E5%9B%9B%E7%AB%A0%E6%8F%90%E5%8D%87/</guid><description>&lt;h2 id="什么是提升"&gt;什么是提升&lt;/h2&gt;
&lt;p&gt;所有的声明（变量或者函数声明）会被移动到各自作用域的最顶端，这个过程被称作&amp;quot;提升&amp;quot;，提升的过程是发生在代码被执行之前的编译阶段，
无论作用域的声明出现在什么地方，都将在代码被执行之前首先处理。&lt;/p&gt;
&lt;h2 id="var-a--2-问题"&gt;var a = 2 问题&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;可以看到，编译时变量a被提升，此处打印出2&lt;/p&gt;
&lt;p&gt;另一个例子&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;以上代码等价于：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;打印出a是undefined是显而易见的&lt;/p&gt;</description></item><item><title>第三章函数作用域和块作用域</title><link>https://xinyuli.blog/zh/2016/12/21/%E7%AC%AC%E4%B8%89%E7%AB%A0%E5%87%BD%E6%95%B0%E4%BD%9C%E7%94%A8%E5%9F%9F%E5%92%8C%E5%9D%97%E4%BD%9C%E7%94%A8%E5%9F%9F/</link><pubDate>Wed, 21 Dec 2016 10:00:00 +0800</pubDate><guid>https://xinyuli.blog/zh/2016/12/21/%E7%AC%AC%E4%B8%89%E7%AB%A0%E5%87%BD%E6%95%B0%E4%BD%9C%E7%94%A8%E5%9F%9F%E5%92%8C%E5%9D%97%E4%BD%9C%E7%94%A8%E5%9F%9F/</guid><description>&lt;h2 id="函数作用域"&gt;函数作用域&lt;/h2&gt;
&lt;p&gt;JavaScript具有函数作用域，主要具有这几点好处:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;隐藏内部实现，符合软件设计中的最小特权原则。&lt;/li&gt;
&lt;li&gt;规避冲突。函数作用域可以当做命名空间隐藏变量，避免暴露到全局作用域发生冲突。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="块作用域"&gt;块作用域&lt;/h2&gt;
&lt;p&gt;虽然函数作用域是JavaScript中最常见的作用域单元，但块作用域在JavaScript中也是存在的，只不过（个人理解）JavaScript中的块作用域只是针对块中的某个变量
来说的。&lt;/p&gt;</description></item><item><title>第二章词法作用域</title><link>https://xinyuli.blog/zh/2016/12/21/%E7%AC%AC%E4%BA%8C%E7%AB%A0%E8%AF%8D%E6%B3%95%E4%BD%9C%E7%94%A8%E5%9F%9F/</link><pubDate>Wed, 21 Dec 2016 08:00:00 +0800</pubDate><guid>https://xinyuli.blog/zh/2016/12/21/%E7%AC%AC%E4%BA%8C%E7%AB%A0%E8%AF%8D%E6%B3%95%E4%BD%9C%E7%94%A8%E5%9F%9F/</guid><description>&lt;h2 id="什么是词法作用域"&gt;什么是词法作用域&lt;/h2&gt;
&lt;p&gt;简单来讲，词法作用域就是定义在词法阶段的作用域，换句话说，词法作用域是由你在写代码时将变量和块作用域写在哪里决定的。&lt;/p&gt;
&lt;h2 id="遮蔽效应"&gt;遮蔽效应&lt;/h2&gt;
&lt;p&gt;作用域查找会在找到第一个匹配的标识符时停止，在多层嵌套的作用域中可以定义同名的标识符，这叫做&amp;quot;遮蔽效应&amp;quot;&lt;/p&gt;
&lt;h2 id="欺骗词法"&gt;欺骗词法&lt;/h2&gt;
&lt;p&gt;欺骗词法作用域会导致性能下降&lt;/p&gt;
&lt;h3 id="eval"&gt;eval&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;eval&lt;/code&gt; 可以对一段包含代码的字符串进行演算，并借此来修改词法作用域。&lt;/p&gt;
&lt;p&gt;非严格模式下，eval会对其所在的词法作用域进行修改，严格模式下，其有自己的词法作用域，不会对所在的词法作用域造成修改。&lt;/p&gt;</description></item><item><title>第一章作用域是什么</title><link>https://xinyuli.blog/zh/2016/12/20/%E7%AC%AC%E4%B8%80%E7%AB%A0%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%98%AF%E4%BB%80%E4%B9%88/</link><pubDate>Tue, 20 Dec 2016 00:00:00 +0800</pubDate><guid>https://xinyuli.blog/zh/2016/12/20/%E7%AC%AC%E4%B8%80%E7%AB%A0%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%98%AF%E4%BB%80%E4%B9%88/</guid><description>&lt;h2 id="编译原理"&gt;编译原理&lt;/h2&gt;
&lt;h3 id="传统编译语言的流程中编译会执行三个步骤"&gt;传统编译语言的流程中，编译会执行三个步骤：&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;分词/词法分析
这个阶段将代码分解成词法单元，比如var a = 2，分解成var、a、=、2&lt;/li&gt;
&lt;li&gt;解析/语法分析
将词法单元转换成抽象语法树(AST)&lt;/li&gt;
&lt;li&gt;代码生成
将抽象语法树转换成可执行代码&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="javascript的编译有什么不同"&gt;JavaScript的编译有什么不同&lt;/h3&gt;
&lt;p&gt;JavaScript的编译过程不是发生在构建之前，而是发生在执行前的几微秒或者更短的时候，因此，JavaScript不会像其它语言那样有大量的时间去做优化。&lt;/p&gt;</description></item></channel></rss>