<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:series="http://unfoldingneurons.com/"
		>
<channel>
	<title>Comments on: 作用域链 词法作用域 与闭包（二）</title>
	<atom:link href="http://www.mikkolee.com/84/feed" rel="self" type="application/rss+xml" />
	<link>http://www.mikkolee.com/84</link>
	<description>关于界面的价值观与方法论</description>
	<lastBuildDate>Sat, 04 Sep 2010 14:28:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: 小麦</title>
		<link>http://www.mikkolee.com/84/comment-page-1#comment-96</link>
		<dc:creator>小麦</dc:creator>
		<pubDate>Mon, 01 Dec 2008 13:34:17 +0000</pubDate>
		<guid isPermaLink="false">http://www.mikkolee.com/?p=84#comment-96</guid>
		<description>呵呵，好长。容许我过段时间再来看。</description>
		<content:encoded><![CDATA[<p>呵呵，好长。容许我过段时间再来看。</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: hax</title>
		<link>http://www.mikkolee.com/84/comment-page-1#comment-94</link>
		<dc:creator>hax</dc:creator>
		<pubDate>Fri, 28 Nov 2008 18:36:42 +0000</pubDate>
		<guid isPermaLink="false">http://www.mikkolee.com/?p=84#comment-94</guid>
		<description>【将JS称为是“静态作用域”语言，确实有点问题！】

哎，你不要把 定义 和 实现 混淆起来嘛。

可以通过静态分析确定作用域，不等于在实践中一定要通过一次性的静态编译过程来确定作用域。否则解释语言岂不是都只能用动态作用域？

再者说，我已经强调过了，JS并不是完全的lexical scope，所以无法仅仅通过静态编译过程来确定作用域。

由上述两点，可以知道认为JS不是“静态作用域”而是“lexical scope”，进而认为static scope不等于lexical scope，纯粹是认识上的误区。Scott的解释完全没有问题。纯粹的静态作用域语言，肯定可以在编译时确定作用域。但是当然也可以留待到运行时确定，这并不矛盾。现有的JS为什么采用在运行时才确定作用域的scope chain机制，是因为JS不是纯粹的静态作用域语言，无法在编译时确定所有的作用域。

再，关于lexical scope和scope chain的关系。

之前已经说过，scope chain只是一种实现手段，可以用来实现静态作用域（当然也可以实现非静态作用域，例如with的构造）。唯一独特的是，ES3规范把scope chain机制写到了规范之内，这可能使人误以为所有JS引擎都必须采用scope chain的方式。从某种程度上说，scope chain不应出现在ES规范中，现在ES3规范中对于scope chain的描述，应该被理解为，通过对此种机制的描述来更准确的定义JS语言的行为，而不是说，JS引擎就必须采用scope chain。

实际上未必如此，只要效果等价，你完全可以用其他方式。许多JS引擎都有优化，即在某些条件下并不使用scope chain机制。

反过来说，之所以现在JS要使用scope chain，也是因为JS不是完全的lexical scope。

未来JS可能加入一个pragma：“use lexical scope”，在开启此pragma之后，不允许使用with结构，不允许在eval中修改当前scope，不允许scope chain上的任何一个属性被delete，总是使用初始的global绑定（即动态的增加一个global变量是不能被访问到的，除非显式的使用window.xxx来访问）……总而言之一句话，允许引擎在这种情况下按照完全的静态作用域方式来确定变量，而不必缓慢的在scope chain上逐级检索。

此外，scope chain机制可以实现closure，但是也并不表示closure一定要用scope chain实现。Python 2.1开始支持static nested scope，它是采用flat closures方式来实现的。Lua也采用flat closures来实现，参见：http://blog.csdn.net/hunhun1981/archive/2008/04/10/2276334.aspx 。如果JS没有with和eval捣蛋，也可以抛开scope chain转用其他方式实现closure。</description>
		<content:encoded><![CDATA[<p>【将JS称为是“静态作用域”语言，确实有点问题！】</p>
<p>哎，你不要把 定义 和 实现 混淆起来嘛。</p>
<p>可以通过静态分析确定作用域，不等于在实践中一定要通过一次性的静态编译过程来确定作用域。否则解释语言岂不是都只能用动态作用域？</p>
<p>再者说，我已经强调过了，JS并不是完全的lexical scope，所以无法仅仅通过静态编译过程来确定作用域。</p>
<p>由上述两点，可以知道认为JS不是“静态作用域”而是“lexical scope”，进而认为static scope不等于lexical scope，纯粹是认识上的误区。Scott的解释完全没有问题。纯粹的静态作用域语言，肯定可以在编译时确定作用域。但是当然也可以留待到运行时确定，这并不矛盾。现有的JS为什么采用在运行时才确定作用域的scope chain机制，是因为JS不是纯粹的静态作用域语言，无法在编译时确定所有的作用域。</p>
<p>再，关于lexical scope和scope chain的关系。</p>
<p>之前已经说过，scope chain只是一种实现手段，可以用来实现静态作用域（当然也可以实现非静态作用域，例如with的构造）。唯一独特的是，ES3规范把scope chain机制写到了规范之内，这可能使人误以为所有JS引擎都必须采用scope chain的方式。从某种程度上说，scope chain不应出现在ES规范中，现在ES3规范中对于scope chain的描述，应该被理解为，通过对此种机制的描述来更准确的定义JS语言的行为，而不是说，JS引擎就必须采用scope chain。</p>
<p>实际上未必如此，只要效果等价，你完全可以用其他方式。许多JS引擎都有优化，即在某些条件下并不使用scope chain机制。</p>
<p>反过来说，之所以现在JS要使用scope chain，也是因为JS不是完全的lexical scope。</p>
<p>未来JS可能加入一个pragma：“use lexical scope”，在开启此pragma之后，不允许使用with结构，不允许在eval中修改当前scope，不允许scope chain上的任何一个属性被delete，总是使用初始的global绑定（即动态的增加一个global变量是不能被访问到的，除非显式的使用window.xxx来访问）……总而言之一句话，允许引擎在这种情况下按照完全的静态作用域方式来确定变量，而不必缓慢的在scope chain上逐级检索。</p>
<p>此外，scope chain机制可以实现closure，但是也并不表示closure一定要用scope chain实现。Python 2.1开始支持static nested scope，它是采用flat closures方式来实现的。Lua也采用flat closures来实现，参见：http://blog.csdn.net/hunhun1981/archive/2008/04/10/2276334.aspx 。如果JS没有with和eval捣蛋，也可以抛开scope chain转用其他方式实现closure。</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: starflash</title>
		<link>http://www.mikkolee.com/84/comment-page-1#comment-92</link>
		<dc:creator>starflash</dc:creator>
		<pubDate>Wed, 26 Nov 2008 07:28:18 +0000</pubDate>
		<guid isPermaLink="false">http://www.mikkolee.com/?p=84#comment-92</guid>
		<description>js 在每个函数被调用时都会创建相应的执行环境，每个函数都是在不同的执行环境中运行的。在该执行环境中会存在一个作用域链，这个作用域链是由——在被调用函数中[[scope]]属性所保存的作用域链的头部添加当前执行环境的调用对象所组成的。

所以回到你举的这个例子来说，f(1)和f(2)运行时创建了2个不同的执行环境，也就产生了2个不同的作用域链，而返回的函数g1和g2内部也就拥有了不同的作用域链，在g1的作用域链中保存x=1，而在g2的作用域链中保存x=2。</description>
		<content:encoded><![CDATA[<p>js 在每个函数被调用时都会创建相应的执行环境，每个函数都是在不同的执行环境中运行的。在该执行环境中会存在一个作用域链，这个作用域链是由——在被调用函数中[[scope]]属性所保存的作用域链的头部添加当前执行环境的调用对象所组成的。</p>
<p>所以回到你举的这个例子来说，f(1)和f(2)运行时创建了2个不同的执行环境，也就产生了2个不同的作用域链，而返回的函数g1和g2内部也就拥有了不同的作用域链，在g1的作用域链中保存x=1，而在g2的作用域链中保存x=2。</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: 大仙</title>
		<link>http://www.mikkolee.com/84/comment-page-1#comment-88</link>
		<dc:creator>大仙</dc:creator>
		<pubDate>Sun, 23 Nov 2008 03:51:50 +0000</pubDate>
		<guid isPermaLink="false">http://www.mikkolee.com/?p=84#comment-88</guid>
		<description>哎，看不懂。希望博主能够更新点CSS标准的东东。</description>
		<content:encoded><![CDATA[<p>哎，看不懂。希望博主能够更新点CSS标准的东东。</p>
]]></content:encoded>
	</item>
</channel>
</rss>
