<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	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:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>七月佑安</title>
	<atom:link href="http://oragg.com/feed" rel="self" type="application/rss+xml" />
	<link>http://oragg.com</link>
	<description>坚持。。。</description>
	<lastBuildDate>Thu, 29 Oct 2009 10:24:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>为Chrome自动切换代理服务器</title>
		<link>http://oragg.com/2009/10/pac-setting-for-google-chrome.html</link>
		<comments>http://oragg.com/2009/10/pac-setting-for-google-chrome.html#comments</comments>
		<pubDate>Sat, 17 Oct 2009 09:13:22 +0000</pubDate>
		<dc:creator>大蒜</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[PAC]]></category>
		<category><![CDATA[Proxy]]></category>

		<guid isPermaLink="false">http://oragg.com/?p=111</guid>
		<description><![CDATA[有些网站使用代理服务器访问比较快，而另外一些恰好相反。在Firefox中，我们可以使用FoxyProxy动态地切换代理服务器，可是Chrome没有这个扩展。最近使用Chrome的时候多了，发现不能切换代理是一件很麻烦的事情。幸好Chrome使用的是Windows全局的代理服务器设置，我们可以借助Windows的PAC（proxy auto-config）功能，来实现同样的效果，PAC文件其实就是一个JScript文件，里面只有一个函数FindProxyForURL，我们在这个函数中编写规则，就可以实现动态配置代理服务器的要求。
首先需要建立一个文本文件，文件名随意，本例中是D:\proxy.pac，具体的内容如下所示：
My PAC Settingfunction FindProxyForURL&#40;url, host&#41; &#123;
&#160; &#160; var proxy1 = &#34;PROXY 127.0.0.1:1984&#34;,
&#160; &#160; &#160; &#160; proxy2 = &#34;PROXY 127.0.0.1:9666&#34;,
&#160; &#160; &#160; &#160; proxy3 = &#34;PROXY 127.0.0.1:8580&#34;,
&#160; &#160; &#160; &#160; proxy4 = &#34;PROXY 127.0.0.1:8000&#34;;
&#160;
&#160; &#160; if &#40;shExpMatch&#40;url,&#34;*blogspot.com*&#34;&#41;&#160; &#160; &#160; &#160; &#160; &#124;&#124;
&#160; &#160; &#160; &#160; shExpMatch&#40;url,&#34;*box.net*&#34;&#41;&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#124;&#124;
&#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>有些网站使用代理服务器访问比较快，而另外一些恰好相反。在Firefox中，我们可以使用FoxyProxy动态地切换代理服务器，可是Chrome没有这个扩展。最近使用Chrome的时候多了，发现不能切换代理是一件很麻烦的事情。幸好Chrome使用的是Windows全局的代理服务器设置，我们可以借助Windows的<a href="http://en.wikipedia.org/wiki/Proxy_auto-config">PAC（proxy auto-config）</a>功能，来实现同样的效果，PAC文件其实就是一个JScript文件，里面只有一个函数FindProxyForURL，我们在这个函数中编写规则，就可以实现动态配置代理服务器的要求。</p>
<p>首先需要建立一个文本文件，文件名随意，本例中是D:\proxy.pac，具体的内容如下所示：<br />
</p><p><strong><a href='http://snipplr.com/view/21386/my-pac-setting'>My PAC Setting</a></strong><br/></p><div class='code' style='border: 1px dotted; overflow: auto; white-space:nowrap;'><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> FindProxyForURL<span style="color: #66cc66;">&#40;</span>url, host<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> proxy1 = <span style="color: #3366CC;">&quot;PROXY 127.0.0.1:1984&quot;</span>,</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; proxy2 = <span style="color: #3366CC;">&quot;PROXY 127.0.0.1:9666&quot;</span>,</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; proxy3 = <span style="color: #3366CC;">&quot;PROXY 127.0.0.1:8580&quot;</span>,</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; proxy4 = <span style="color: #3366CC;">&quot;PROXY 127.0.0.1:8000&quot;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*blogspot.com*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*box.net*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*chromeexperiments.com*&quot;</span><span style="color: #66cc66;">&#41;</span> ||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*chromium.org*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*facebook.com*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*meme.yahoo.com*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; ||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*opera.com*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*twitter.com*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*youtube.com*&quot;</span><span style="color: #66cc66;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;||</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; shExpMatch<span style="color: #66cc66;">&#40;</span>url,<span style="color: #3366CC;">&quot;*ytimg.com*&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> proxy1;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">&quot;DIRECT&quot;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span> </div></li></ol></div><p></p>
<p>在google菜单中的 选项/高级选项/网络/更改代理设置/局域网设置 中勾选使用自动配置脚本，并且设置地址为 file://d:/proxy.pac。</p>
<p>这样在启动代理服务器以后，再运行Chrome浏览器访问上面的地址，就会根据规则有选择的用代理服务器访问了。需要注意的是，如果在本地修改了PAC规则，那么需要将Chrome重新启动后，规则才能生效。</p>
<p>参考资料：<br />
* <a href="http://www.livid.cn/doc_view.php?doc_id=5744">http://www.livid.cn/doc_view.php?doc_id=5744</a><br />
* <a href="http://en.wikipedia.org/wiki/Proxy_auto-config">http://en.wikipedia.org/wiki/Proxy_auto-config</a><br />
* <a href="http://findproxyforurl.com/">http://findproxyforurl.com/</a><br />
* <a href="http://technet.microsoft.com/en-us/library/dd361950.aspx">http://technet.microsoft.com/en-us/library/dd361950.aspx</a><br />
* <a href="http://web.archive.org/web/20060424005037/wp.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html">http://wp.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html</a><br />
* <a href="http://web.archive.org/web/20040810122331/http://developer.netscape.com/docs/manuals/proxy/adminux/autoconf.htm">http://developer.netscape.com/docs/manuals/proxy/adminux/autoconf.htm</a><br />
* <a href="http://www.returnproxy.com/">http://www.returnproxy.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://oragg.com/2009/10/pac-setting-for-google-chrome.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在WordPress中插入Snipplr上的代码片段</title>
		<link>http://oragg.com/2009/10/snipplr-for-wordpress.html</link>
		<comments>http://oragg.com/2009/10/snipplr-for-wordpress.html#comments</comments>
		<pubDate>Sat, 17 Oct 2009 05:14:29 +0000</pubDate>
		<dc:creator>大蒜</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Snipplr]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://oragg.com/?p=95</guid>
		<description><![CDATA[Snipplr是一个非常不错的分享代码片段的网站，同时附带各种工具，除了在这个网站上互相分享之外，还可以将代码片段插入到Textmate或者WordPress中，下面就是WordPress下的一个实例：
pick a certain substring from a string by regular expressionfunction pick&#40;str, re&#41; &#123;
&#160; var result = str.match&#40;re&#41;;
&#160; return &#40;result &#38;&#38; result.length === 2&#41; ? result&#91;1&#93; : result;
&#125;
&#160;
var str = &#34;tel: 13512345678&#34;;
var tel_a = pick&#40;str, /tel:\s?&#40;\d+&#41;/&#41;;
var tel_b = pick&#40;str, /tel:&#40;\d+&#41;/&#41;;
&#160;
// return 13512345678
alert&#40;tel_a&#41;;
&#160;
// return null
alert&#40;tel_b&#41;; 
以上的功能是通过Snipplr for WordPress来实现的。安装了这个插件以后，就可以通过下面的方式，将一个代码片段插入到文章中。
Insert a snippet into your wordpress article[snippet=21219]
在这个插件的设置页面，提供了一些很方便的选项，最重要的是要设置api key，这个可以在Snipplr的设置页面中找到，不设置这个东东，插件是不会起作用的。
还可以设置一些开关选项，比如是否显示行号、标题、作者、评论以及是否进行语法渲染等。要了解更多的功能，大家除了可以直接试用以外，还可以来参考Snipplr提供的入门视频。
类似Snipplr这种public source code [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://snipplr.com/">Snipplr</a>是一个非常不错的分享代码片段的网站，同时附带<a href="http://snipplr.com/developer/">各种工具</a>，除了在这个网站上互相分享之外，还可以将代码片段插入到<a href="http://snipplr.com/developer/textmate/">Textmate</a>或者<a href="http://snipplr.com/developer/wordpress/">WordPress</a>中，下面就是WordPress下的一个实例：</p>
<p></p><p><strong><a href='http://snipplr.com/view/21219/pick-a-certain-substring-from-a-string-by-regular-expression'>pick a certain substring from a string by regular expression</a></strong><br/></p><div class='code' style='border: 1px dotted; overflow: auto; white-space:nowrap;'><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> pick<span style="color: #66cc66;">&#40;</span>str, re<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #003366; font-weight: bold;">var</span> result = str.<span style="color: #006600;">match</span><span style="color: #66cc66;">&#40;</span>re<span style="color: #66cc66;">&#41;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #66cc66;">&#40;</span>result &amp;&amp; result.<span style="color: #006600;">length</span> === <span style="color: #CC0000;">2</span><span style="color: #66cc66;">&#41;</span> ? result<span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#93;</span> : result;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> str = <span style="color: #3366CC;">&quot;tel: 13512345678&quot;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> tel_a = pick<span style="color: #66cc66;">&#40;</span>str, <span style="color: #0066FF;">/tel:\s?<span style="color: #66cc66;">&#40;</span>\d+<span style="color: #66cc66;">&#41;</span>/</span><span style="color: #66cc66;">&#41;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">var</span> tel_b = pick<span style="color: #66cc66;">&#40;</span>str, <span style="color: #0066FF;">/tel:<span style="color: #66cc66;">&#40;</span>\d+<span style="color: #66cc66;">&#41;</span>/</span><span style="color: #66cc66;">&#41;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">// return 13512345678</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span>tel_a<span style="color: #66cc66;">&#41;</span>;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">// return null</span></div></li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000066;">alert</span><span style="color: #66cc66;">&#40;</span>tel_b<span style="color: #66cc66;">&#41;</span>; </div></li></ol></div><p></p>
<p>以上的功能是通过<a href="http://snipplr.com/developer/wordpress/">Snipplr for WordPress</a>来实现的。安装了这个插件以后，就可以通过下面的方式，将一个代码片段插入到文章中。</p>
<p></p><p><strong><a href='http://snipplr.com/view/21383/insert-a-snippet-into-your-wordpress-article'>Insert a snippet into your wordpress article</a></strong><br/></p><div class='code' style='border: 1px dotted; overflow: auto; white-space:nowrap;'><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">[snippet=21219]</div></li></ol></div><p></p>
<p>在这个插件的设置页面，提供了一些很方便的选项，最重要的是要设置api key，这个可以在<a href="http://snipplr.com/settings/">Snipplr的设置页面</a>中找到，不设置这个东东，插件是不会起作用的。</p>
<p>还可以设置一些开关选项，比如是否显示行号、标题、作者、评论以及是否进行语法渲染等。要了解更多的功能，大家除了可以直接试用以外，还可以来参考Snipplr提供的<a href="http://snipplr.com/images/wordpress.mov">入门视频</a>。</p>
<p>类似Snipplr这种public source code repository工具，其实还是有一些的，比如下面几个：<br />
* <a href="http://snippets.dzone.com/">http://snippets.dzone.com/</a><br />
* <a href="http://codesnippets.joyent.com/">http://codesnippets.joyent.com/</a><br />
* <a href="http://css-tricks.com/snippets/">http://css-tricks.com/snippets/</a>（这个性质不一样，但是确实也提供不少的代码片段）</p>
<p>更新：由于语法渲染的样式都是通过Inline CSS设置的，所以在Google Reader下看还是很正常的，和页面基本保持一致。</p>
<p>更新：用了一会儿，发现这东东也是有缺点的，就是不能切换显示模式和纯文本模式，带来的直接问题就是看着好看，但是不能轻易的复制粘贴。如果把行号去掉呢，虽然复制可以直接用了，但是看着还是很不美观的。snipplr上的页面，倒是有这个功能，可是跳转到那边复制毕竟还是很麻烦的啊。</p>
]]></content:encoded>
			<wfw:commentRss>http://oragg.com/2009/10/snipplr-for-wordpress.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://snipplr.com/images/wordpress.mov" length="15079773" type="video/quicktime" />
		</item>
		<item>
		<title>如何使用VirtualBox 3在Windows主机下架设桥接网络</title>
		<link>http://oragg.com/2009/10/virtualbox-3-and-bridged-networking-on-xp-hos.html</link>
		<comments>http://oragg.com/2009/10/virtualbox-3-and-bridged-networking-on-xp-hos.html#comments</comments>
		<pubDate>Sun, 11 Oct 2009 12:09:18 +0000</pubDate>
		<dc:creator>大蒜</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Bridged Networking]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://oragg.com/?p=87</guid>
		<description><![CDATA[在以前的一篇文章中，我曾经介绍过当主机是Windows XP的情况下，如何为Ubuntu客户机搭建桥接网络，那时候使用的虚拟机是Virtualbox 2.0.6。其实还是蛮麻烦的，需要建立虚拟网卡，还要搭桥。时过境迁，当我再次搭虚拟机的时候，发现Virtualbox已经升级到了3.0.8，而且还内置了桥接网络的功能，我们现在只需要很少的设置就可以完成桥接网络的搭建。
先说下我的环境：
主机：Windows XP Service Pack 3
客户机：Ubuntu Server 9.04（minimal virtual machine mode）
虚拟机：VirtualBox 3.0.8 for Windows hosts
由于Virtualbox 3.0.8已经内置了桥接网络的功能，所以我们只需要在网卡上安装相应的服务就可以。具体为：控制面板/网络连接/本地连接/属性/安装/服务/VirtualBox Bridged Networking Driver。添加了这个服务以后，打开虚拟机的设置窗口，进入网络选项卡，将网络连接1中的连接方式从默认的NAT修改为Bridged Adapter，在下面的名称中选择你电脑本地连接对应的网卡（如果这里没有显示网卡，而是显示未选择，说明没有安装了桥接服务的网卡，需要重复上一步）。
经过上面这步的设置，如果客户机的IP地址设置为DHCP模式，那现在应该就可以正常访问网络了。如果不想动态分配IP地址，可以再按照下面的方式设置IP和DNS。

$ sudo vi /etc/network/interfaces
auto eth0
iface eth0 inet static
address 192.168.0.120
gateway 192.168.0.1
netmask 255.255.255.0

$ sudo vi /etc/resolv.conf
nameserver 208.67.222.222
nameserver 208.67.220.220

$ sudo /etc/init.d/networking restart

上面的设置，除了IP以外，其他要和主机上的设置保持一致。在这里使用了eth0，但是需要注意的是，由于添加了虚拟网卡的缘故，在你的虚拟机中有可能不是eth0，而是eth1或者eth2等，这个需要根据实际情况来设置，具体是什么，可以通过下面的命令来查询：

$ ifconfig -a

如果将eth1等名称设置为eth0的话，所有的设置是无效的，而且在启动网络服务的时候，会得到如下错误信息：

SIOCSIFADDR: No such device
eth0: ERROR while getting interface flags: No such device
SIOCSIFNETMASK: No such device
eth0: [...]]]></description>
			<content:encoded><![CDATA[<p>在<a href="http://cuimingda.blogspot.com/2009/01/virtualbox-host-interface-for-windows.html">以前的一篇文章</a>中，我曾经介绍过当主机是Windows XP的情况下，如何为Ubuntu客户机搭建桥接网络，那时候使用的虚拟机是Virtualbox 2.0.6。其实还是蛮麻烦的，需要建立虚拟网卡，还要搭桥。时过境迁，当我再次搭虚拟机的时候，发现Virtualbox已经升级到了3.0.8，而且还内置了桥接网络的功能，我们现在只需要很少的设置就可以完成桥接网络的搭建。</p>
<p>先说下我的环境：<br />
主机：<a href="http://www.microsoft.com/windows/windows-XP/">Windows XP Service Pack 3</a><br />
客户机：<a href="http://www.microsoft.com/windows/windows-XP/">Ubuntu Server 9.04（minimal virtual machine mode）</a><br />
虚拟机：<a href="http://www.virtualbox.org/wiki/Downloads">VirtualBox 3.0.8 for Windows hosts</a></p>
<p>由于Virtualbox 3.0.8已经内置了桥接网络的功能，所以我们只需要在网卡上安装相应的服务就可以。具体为：<strong>控制面板/网络连接/本地连接/属性/安装/服务/VirtualBox Bridged Networking Driver</strong>。添加了这个服务以后，打开虚拟机的设置窗口，进入<strong>网络</strong>选项卡，将<strong>网络连接1</strong>中的连接方式从默认的<strong>NAT</strong>修改为<strong>Bridged Adapter</strong>，在下面的名称中选择你电脑本地连接对应的网卡（如果这里没有显示网卡，而是显示<strong>未选择</strong>，说明没有安装了桥接服务的网卡，需要重复上一步）。</p>
<p>经过上面这步的设置，如果客户机的IP地址设置为DHCP模式，那现在应该就可以正常访问网络了。如果不想动态分配IP地址，可以再按照下面的方式设置IP和DNS。</p>
<pre class="source-code">
$ sudo vi /etc/network/interfaces
auto eth0
iface eth0 inet static
address 192.168.0.120
gateway 192.168.0.1
netmask 255.255.255.0

$ sudo vi /etc/resolv.conf
nameserver 208.67.222.222
nameserver 208.67.220.220

$ sudo /etc/init.d/networking restart
</pre>
<p>上面的设置，除了IP以外，其他要和主机上的设置保持一致。在这里使用了eth0，但是需要注意的是，由于添加了虚拟网卡的缘故，在你的虚拟机中有可能不是eth0，而是eth1或者eth2等，这个需要根据实际情况来设置，具体是什么，可以通过下面的命令来查询：</p>
<pre class="source-code">
$ ifconfig -a
</pre>
<p>如果将eth1等名称设置为eth0的话，所有的设置是无效的，而且在启动网络服务的时候，会得到如下错误信息：</p>
<pre class="source-code">
SIOCSIFADDR: No such device
eth0: ERROR while getting interface flags: No such device
SIOCSIFNETMASK: No such device
eth0: ERROR while getting interface flags: No such device
Failed to bring up eth0
</pre>
<p>基本上经过了以上的设置，网络就应该已经OK了，可以在客户机上直接ping一下其他的地址来进行测试：</p>
<pre class="source-code">
$ ping -c 4 192.168.0.1
$ ping -c 4 koubei.com
</pre>
<p>补充一点，VirtualBox 2.x时代建立的虚拟网卡和网络桥，现在已经没有用了，网络桥可以直接删除，虚拟网卡可以在设备管理器中删除，也可以在<strong>VirtualBox/全局设定/网络</strong>中删除。</p>
<p>再补充一下NAT和桥接的区别，简单来说，如果使用NAT，客户机和主机是公用一套网络资源的，优势就是简单，什么都不用设置，主机可以正常上网，客户机就可以正常上网，缺点就是，局域网中其他机器是访问不到这个虚拟机的，而我的虚拟机主要是用来架设LAMP的，无法被访问当然不符合要求；这就是桥接网络的优势，可以将虚拟机模拟成具体网中的独立节点，和其他电脑的地位是一致的，可以访问别人，也可以被别人访问，当然，如果是在公司架设的话，这个肯定要受限制了，毕竟很多公司的IP地址都是和Mac地址绑定的。所以，具体使用哪种方式连接网络，完全根据实际需要而定。</p>
<p>参考资料：<br />
# <a href="http://cuimingda.blogspot.com/2009/01/set-ip-and-dns-for-ubuntu.html">http://cuimingda.blogspot.com/2009/01/set-ip-and-dns-for-ubuntu.html</a><br />
# <a href="http://cuimingda.blogspot.com/2009/01/virtualbox-host-interface-for-windows.html">http://cuimingda.blogspot.com/2009/01/virtualbox-host-interface-for-windows.html</a><br />
# <a href="http://ubuntuforums.org/showthread.php?t=221768">http://ubuntuforums.org/showthread.php?t=221768</a><br />
# <a href="http://www.edwardstafford.com/2009/09/13/virtualbox-3-0-4-and-bridged-networking-on-xp-host-with-gui/">http://www.edwardstafford.com/2009/09/13/virtualbox-3-0-4-and-bridged-networking-on-xp-host-with-gui/</a><br />
# <a href="http://forums.virtualbox.org/viewtopic.php?t=21907">http://forums.virtualbox.org/viewtopic.php?t=21907</a><br />
# <a href="http://forums.virtualbox.org/viewtopic.php?t=21029">http://forums.virtualbox.org/viewtopic.php?t=21029</a><br />
# <a href="http://www.hacklog.cn/linux/sun-virtualbox-3-0-bridge-setup-on-ubuntu-9-0-4.html">http://www.hacklog.cn/linux/sun-virtualbox-3-0-bridge-setup-on-ubuntu-9-0-4.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://oragg.com/2009/10/virtualbox-3-and-bridged-networking-on-xp-hos.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何安装最新版本的Chrome</title>
		<link>http://oragg.com/2009/09/howto-setup-lastest-chrome.html</link>
		<comments>http://oragg.com/2009/09/howto-setup-lastest-chrome.html#comments</comments>
		<pubDate>Thu, 17 Sep 2009 16:44:00 +0000</pubDate>
		<dc:creator>大蒜</dc:creator>
				<category><![CDATA[Original]]></category>
		<category><![CDATA[Chrome]]></category>

		<guid isPermaLink="false">http://oragg.com/?p=69</guid>
		<description><![CDATA[介绍Chrome和Chromium的关系，以及去哪里可以下载最新的Chromium。]]></description>
			<content:encoded><![CDATA[<p>说到最新版本的Chrome，就要说说Chromium。Chromium是一个由Google主导开发的开源浏览器，始于2006年，也可以理解为就是Chrome的开发版，一些最新的功能总是会先在Chromium中测试，然后才会应用在Chrome中。比如大家在一些下载网站上看到的Chrome 4，其实准确的说应该是Chromium 4，比如我刚下了一个最新版本，版本号是<a href="http://build.chromium.org/buildbot/snapshots/chromium-rel-xp/26446/chrome-win32.zip">Chromium 4.0.212.0 (26446)</a>。Chromium的发布速度是很快的，一天发布四五个Build是常用的事情。就在我编辑这篇文章的时间里，最新的Build就已经从26446升级到26450了，呵呵。</p>
<p>大家可以在这个地址找到Chromium在Windows下的版本：<br />
<a href="http://build.chromium.org/buildbot/snapshots/chromium-rel-xp/">http://build.chromium.org/buildbot/snapshots/chromium-rel-xp/</a></p>
<p>里面有几种类型的安装文件，包括开发版、测试版和发布版，建议使用chrome-win32.zip，解压缩就可以使用，完全绿色的版本。如果要更新版本，只要将新版本的文件覆盖到老版本的目录就OK了，还是很方便的。</p>
<p>如果你感觉经常更新是件很麻烦的事情，也不用着急，因为已经有人对频繁更新也不耐烦了，所以开发了一个自动更新的小工具<a href="http://dirhael.dcmembers.com/cnu/">Chromium Nightly Updater</a>，完全可以解决更新的问题。</p>
<p>都说Chromium 4的速度现在已经可以和<a href="http://www.opera.com/browser/">Opera 10</a>媲美了，让我们一起去体验飞一般的速度吧。^_^</p>
<p>更新（2009年09月26日）：</p>
<p>当安装了最新的Chromium后，还可以体验一些Firefox下口碑很好的功能，比如<a href="http://code.google.com/chrome/extensions">Extensions</a>和<a href="http://dev.chromium.org/developers/design-documents/user-scripts">User Scripts</a>。当然，如果你对Chrome扩展感兴趣，还可以看看<a href="http://www.chromeplugins.org/">Chrome Plugins</a>这个网站，可是和Chrome同龄的哟。</p>
<p><img alt="" src="http://hortont.com/files/chromium.png" class="alignnone" width="256" height="256" /></p>
<p>更新（2009-10-18）</p>
<p>Chromium是给体验最新Chrome技术的朋友的玩具，对于大部分用户，大家需要记住只有两个版本，一个是<a href="https://tools.google.com/chrome/">Google Chrome</a>，另外一个就是<a href="http://www.google.com/intl/en/landing/chrome/beta/">Google Chrome Beta</a>。点击这两个页面中的下载按钮下载下来的安装程序都是最小版，就是运行了以后还会再下载的那种，要想下载完整版，只需要在下载地址后面加上standalone=1这个参数就可以。</p>
<p>比如页面上提供的Google Chrome的下载地址是：<br />
<a href="https://tools.google.com/chrome/eula.html">https://tools.google.com/chrome/eula.html</a></p>
<p>那么Google Chrome完整版的安装包就对应下面这个地址：<br />
<a href="https://tools.google.com/chrome/eula.html?standalone=1">https://tools.google.com/chrome/eula.html?standalone=1</a></p>
<p>更新（2009年10月29日）</p>
<p>下载的Chromium Zip包里面的目录固定叫做chrome-win32，所以可以将这个目录解压缩到D:\chrome-win32，而且连配置文件都可以放在这个目录里面，这样以后升级Chromium，只要将新文件放在这个目录覆盖原文件就可以了。比如本例我们可以建立一个快捷方式，目标设置为下面这样：</p>
<p>D:\chrome-win32\chrome.exe &#8211;user-data-dir=D:\chrome-win32</p>
<p>这样以后我们只要将这个目录复制走，所以的配置也就相应的复制走，一个绿色版也就这么打造出来了。</p>
<p>参考资料：<br />
* <a href="http://zh.wikipedia.org/wiki/Chromium_(%E7%80%8F%E8%A6%BD%E5%99%A8)">http://zh.wikipedia.org/wiki/Chromium_(%E7%80%8F%E8%A6%BD%E5%99%A8)</a><br />
* <a href="http://www.chrome-bbs.cn/thread.php?fid=3">http://www.chrome-bbs.cn/thread.php?fid=3</a><br />
* <a href="http://www.appinn.com/chromium-nightly-updater/">http://www.appinn.com/chromium-nightly-updater/</a><br />
* <a href="http://blog.chromium.org/">http://blog.chromium.org/</a><br />
* <a href="http://dev.chromium.org/">http://dev.chromium.org/</a><br />
* <a href="http://code.google.com/chromium/">http://code.google.com/chromium/</a><br />
* <a href="http://www.chromepub.com/article/google-standalone-chrome-20090907.html">http://www.chromepub.com/article/google-standalone-chrome-20090907.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://oragg.com/2009/09/howto-setup-lastest-chrome.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>在JavaScript中，为什么要尽可能使用局部变量？</title>
		<link>http://oragg.com/2009/06/javascript-variable-performance.html</link>
		<comments>http://oragg.com/2009/06/javascript-variable-performance.html#comments</comments>
		<pubDate>Mon, 15 Jun 2009 09:13:26 +0000</pubDate>
		<dc:creator>大蒜</dc:creator>
				<category><![CDATA[Translation]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Variables]]></category>

		<guid isPermaLink="false">http://oragg.com/?p=48</guid>
		<description><![CDATA[本文译自Nicholas C. Zakas于2009年2月10日在个人网站上发表的《JavaScript Variable Performance》。原文是唯一的正式版，本文是经过原文作者授权的简体中文翻译版。译者在翻译的准确性上做了大量的努力，并承诺译文的内容完全忠于原文，但可能还是包含疏漏和不妥之处，欢迎大家指正。译序和译注的内容是非正式的，仅代表译者个人观点。
译者序：在JavaScript中，我们应该尽可能的用局部变量来代替全局变量，这句话所有人都知道，可是这句话是谁先说的？为什么要这么做？有什么根据么？不这么做，对性能到底能带来多大的损失？本文就来探讨这些问题的答案，从根本上了解变量的读写性能都和哪些因素有关。
以下是对原文的翻译：
在如何提高JavaScript性能这个问题上，大家最常听到的建议应该就是尽量使用局部变量（local variables）来代替全局变量（global variables）。在我从事Web开发工作的九年时间里，这条建议始终萦绕在我的耳边，并且从来没有质疑过，而这条建议的基础，则来自于 JavaScript处理作用域（scoping）和标识符解析（identifier resolution）的方法。
首先我们要明确，函数在JavaScript中具体表现为对象，创建一个函数的过程，其实也就是创建一个对象的过程。每个函数对象都有一个叫做 [[Scope]]的内部属性，这个内部属性包含创建函数时的作用域信息。实际上，[[Scope]]属性对应的是一个对象（Variable Objects）列表，列表中的对象是可以从函数内部访问的。比如说我们建立一个全局函数A，那么A的[[Scope]]内部属性中只包含一个全局对象（Global Object），而如果我们在A中创建一个新的函数B，那么B的[[Scope]]属性中就包含两个对象，函数A的Activation Object对象在前面，全局对象（Global Object）排在后面。
当一个函数被执行的时候，会自动创建一个可以执行的对象（Execution Object），并同时绑定一个作用域链（Scope Chain）。作用域链会通过下面两个步骤来建立，用于进行标识符解析。
 1. 首先将函数对象[[Scope]]内部属性中的对象，按顺序复制到作用域链中。
 2. 其次，在函数执行时，会创建一个新的Activation Object对象，这个对象中包含了this、参数（arguments）、局部变量（包括命名的参数）的定义，这个Activation Object对象会被置于作用域链的最前面。
在执行JavaScript代码的过程中，当遇到一个标识符，就会根据标识符的名称，在执行上下文（Execution Context）的作用域链中进行搜索。从作用域链的第一个对象（该函数的Activation Object对象）开始，如果没有找到，就搜索作用域链中的下一个对象，如此往复，直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象，也就是全局对象（Global Object）以后也没有找到，则会抛出一个错误，提示用户该变量未定义（undefined）。这是在ECMA-262标准中描述的函数执行模型和标识符解析（Identifier Resolution）的过程，事实证明，大部分的JavaScript引擎确实也是这样实现的。需要注意的是，ECMA-262并没有强制要求采用这种结构，只是对这部分功能加以描述而已。
了解标识符解析（Identifier Resolution）的过程以后，我们就能明白为什么局部变量的解析速度要比其他作用域的变量快，主要是由于搜索过程被大幅缩短了。但是，具体会快多少呢？为了回答这个问题，我模拟了一系列的测试，来测试不同作用域深度中变量的性能。
第一个测试是向一个变量中写入一个最简单的值（这里使用字面量的数值1），结果如下图显示，很有趣：

从结果中不难看出，当标识符解析的过程需要进行深度搜索时，会伴随性能损失，而且性能损失的程度会随着标识符深度的增加而递增。意料之中的是，Internet Explorer表现的是最差的（但公平的说，IE 8还是有一些改善的）。值得注意的是，这里有一些例外情况，Google Chrome和最新的WebKit午夜版在访问变量的时间保持得很稳定，不会随着作用域深度的递增而增长。当然，这应该归功于它们所使用的下一代 JavaScript引擎，V8和SquirrelFish。这些引擎在执行代码时进行了优化，而且很明显，这些优化使访问变量的速度比以往更快。 Opera表现的也很不错，比IE、Firefox和当前版本的Safari要快的多，但比基于V8和Squirrelfish的浏览器要慢。 Firefox 3.1 Beta 2的表现有点出人意料，对于局部变量执行的效率非常高，但随着作用域层数的增加，效率便大打折扣。需要注意的是，我这里使用的都是默认设置，也就是说 Firefox是没有开启Trace功能的。
上面的结果是通过对变量执行写操作而得出的，其实我很好奇，读取变量时的情况会不会有什么不同，于是接着做了下面的测试。结果发现，读的速度要比写的速度快一些，但是性能变化的趋势是一致的。

和上个测试一样，Internet Explorer和Firefox还是最慢的，Opera表现了非常抢眼的性能，而同样的，Chrome和最新版本的Webkit午夜版显示了和作用域深度无关的性能趋势，同样需要注意的是，Firefox 3.1 Beta 2的变量访问时间还是会伴随着深度出现一个奇怪的跳跃。
在测试的过程中，我发现一个有趣的现象，就是Chrome在访问全局变量的时候会有额外的性能损失。访问全局变量的时间和作用域层数没有关系，但是会比访问同样层数的局部变量的时间多出50%。
这两个测试可以给我们带来什么启示呢？首先是验证了那个古老的观点，就是要尽可能的使用局部变量。在所有的浏览器下，访问局部变量都比访问跨作用域的变量要快，当然也包括全局变量。下面这几点应该是通过这个测试得出的经验吧：
* 仔细检查函数中所有使用的变量，如果有一个变量不是当前作用域定义的，而且使用了不止一次，那么我们就应该把这个变量保存在局部变量中，而使用这个局部变量来进行读写操作。这样可以帮助我们将作用域外的变量的搜索深度减少到1.这对全局变量尤为重要，因为全局变量总是被放到作用域链的最后位置来搜索。
* 避免使用with语句。因为它会修改执行上下文（Execution Context）的作用域链，在最前面添加一个对象（Variable Object）。这就意味着在执行with的过程中，实际上的局部变量都被移到作用域链上的第二个位置，这会带来性能上的损失。
* 如果你确定一段代码肯定会抛出异常，那么就要避免使用try-catch，因为catch分支在作用域链上的处理方法和with是一样的。但try分支的代码是没有性能损失的，所以还是建议用try-catch来捕获那些不可预知的错误。
如果你想围绕这个话题展开更多的讨论，我在上个月的Mountain View JavaScript Meetup中曾经发表了一个小演讲。可以在SlideShare上下载幻灯片，或者观看聚会的完整视频，我的演讲大概从11分钟左右时开始。
译者笔记
大家如果在阅读本文的过程中，有什么疑惑，建议延伸阅读以下两篇文章：
* Richie写的《JavaScript对象模型-执行模型》
* 《ECMA-262第三版》，主要看看第十章，就是执行上下文（Execution Context）那张，本文提到的名词在那里都有详细的解释。
在最后的时候，Nicholas提到一个Mountain View JavaScript Meetup，Meetup那个网站其实就是一个各种现实世界活动的组织网站，需要翻墙才能访问，住在California真幸福，有那么多的好活动可以参加，呵呵。
]]></description>
			<content:encoded><![CDATA[<p>本文译自<a href="http://www.nczonline.net/contact/">Nicholas C. Zakas</a>于2009年2月10日在<a href="http://www.nczonline.net/">个人网站</a>上发表的《<a href="http://www.nczonline.net/blog/2009/02/10/javascript-variable-performance/">JavaScript Variable Performance</a>》。原文是唯一的正式版，本文是经过原文作者授权的简体中文翻译版。译者在翻译的准确性上做了大量的努力，并承诺译文的内容完全忠于原文，但可能还是包含疏漏和不妥之处，欢迎大家指正。译序和译注的内容是非正式的，仅代表译者个人观点。</p>
<p>译者序：在JavaScript中，我们应该尽可能的用局部变量来代替全局变量，这句话所有人都知道，可是这句话是谁先说的？为什么要这么做？有什么根据么？不这么做，对性能到底能带来多大的损失？本文就来探讨这些问题的答案，从根本上了解变量的读写性能都和哪些因素有关。</p>
<p>以下是对原文的翻译：</p>
<p>在如何提高JavaScript性能这个问题上，大家最常听到的建议应该就是尽量使用局部变量（local variables）来代替全局变量（global variables）。在我从事Web开发工作的九年时间里，这条建议始终萦绕在我的耳边，并且从来没有质疑过，而这条建议的基础，则来自于 JavaScript处理作用域（scoping）和标识符解析（identifier resolution）的方法。</p>
<p>首先我们要明确，函数在JavaScript中具体表现为对象，创建一个函数的过程，其实也就是创建一个对象的过程。每个函数对象都有一个叫做 [[Scope]]的内部属性，这个内部属性包含创建函数时的作用域信息。实际上，[[Scope]]属性对应的是一个对象（Variable Objects）列表，列表中的对象是可以从函数内部访问的。比如说我们建立一个全局函数A，那么A的[[Scope]]内部属性中只包含一个全局对象（Global Object），而如果我们在A中创建一个新的函数B，那么B的[[Scope]]属性中就包含两个对象，函数A的Activation Object对象在前面，全局对象（Global Object）排在后面。</p>
<p>当一个函数被执行的时候，会自动创建一个可以执行的对象（Execution Object），并同时绑定一个作用域链（Scope Chain）。作用域链会通过下面两个步骤来建立，用于进行标识符解析。</p>
<p> 1. 首先将函数对象[[Scope]]内部属性中的对象，按顺序复制到作用域链中。<br />
 2. 其次，在函数执行时，会创建一个新的Activation Object对象，这个对象中包含了this、参数（arguments）、局部变量（包括命名的参数）的定义，这个Activation Object对象会被置于作用域链的最前面。</p>
<p>在执行JavaScript代码的过程中，当遇到一个标识符，就会根据标识符的名称，在执行上下文（Execution Context）的作用域链中进行搜索。从作用域链的第一个对象（该函数的Activation Object对象）开始，如果没有找到，就搜索作用域链中的下一个对象，如此往复，直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象，也就是全局对象（Global Object）以后也没有找到，则会抛出一个错误，提示用户该变量未定义（undefined）。这是在ECMA-262标准中描述的函数执行模型和标识符解析（Identifier Resolution）的过程，事实证明，大部分的JavaScript引擎确实也是这样实现的。需要注意的是，<a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262</a>并没有强制要求采用这种结构，只是对这部分功能加以描述而已。</p>
<p>了解标识符解析（Identifier Resolution）的过程以后，我们就能明白为什么局部变量的解析速度要比其他作用域的变量快，主要是由于搜索过程被大幅缩短了。但是，具体会快多少呢？为了回答这个问题，我模拟了一系列的测试，来测试不同作用域深度中变量的性能。</p>
<p>第一个测试是向一个变量中写入一个最简单的值（这里使用字面量的数值1），结果如下图显示，很有趣：</p>
<p><img src="http://www.nczonline.net/blog/wp-content/uploads/2009/02/variable_write_performance2.png" alt="JavaScript Variable Write Performance" /></p>
<p>从结果中不难看出，当标识符解析的过程需要进行深度搜索时，会伴随性能损失，而且性能损失的程度会随着标识符深度的增加而递增。意料之中的是，Internet Explorer表现的是最差的（但公平的说，IE 8还是有一些改善的）。值得注意的是，这里有一些例外情况，Google Chrome和最新的WebKit午夜版在访问变量的时间保持得很稳定，不会随着作用域深度的递增而增长。当然，这应该归功于它们所使用的下一代 JavaScript引擎，V8和SquirrelFish。这些引擎在执行代码时进行了优化，而且很明显，这些优化使访问变量的速度比以往更快。 Opera表现的也很不错，比IE、Firefox和当前版本的Safari要快的多，但比基于V8和Squirrelfish的浏览器要慢。 Firefox 3.1 Beta 2的表现有点出人意料，对于局部变量执行的效率非常高，但随着作用域层数的增加，效率便大打折扣。需要注意的是，我这里使用的都是默认设置，也就是说 Firefox是没有开启Trace功能的。</p>
<p>上面的结果是通过对变量执行写操作而得出的，其实我很好奇，读取变量时的情况会不会有什么不同，于是接着做了下面的测试。结果发现，读的速度要比写的速度快一些，但是性能变化的趋势是一致的。</p>
<p><img src="http://www.nczonline.net/blog/wp-content/uploads/2009/02/variable_read_performance2.png" alt="JavaScript Variable Read Performance" /></p>
<p>和上个测试一样，Internet Explorer和Firefox还是最慢的，Opera表现了非常抢眼的性能，而同样的，Chrome和最新版本的Webkit午夜版显示了和作用域深度无关的性能趋势，同样需要注意的是，Firefox 3.1 Beta 2的变量访问时间还是会伴随着深度出现一个奇怪的跳跃。</p>
<p>在测试的过程中，我发现一个有趣的现象，就是Chrome在访问全局变量的时候会有额外的性能损失。访问全局变量的时间和作用域层数没有关系，但是会比访问同样层数的局部变量的时间多出50%。</p>
<p>这两个测试可以给我们带来什么启示呢？首先是验证了那个古老的观点，就是要尽可能的使用局部变量。在所有的浏览器下，访问局部变量都比访问跨作用域的变量要快，当然也包括全局变量。下面这几点应该是通过这个测试得出的经验吧：</p>
<p>* 仔细检查函数中所有使用的变量，如果有一个变量不是当前作用域定义的，而且使用了不止一次，那么我们就应该把这个变量保存在局部变量中，而使用这个局部变量来进行读写操作。这样可以帮助我们将作用域外的变量的搜索深度减少到1.这对全局变量尤为重要，因为全局变量总是被放到作用域链的最后位置来搜索。<br />
* 避免使用with语句。因为它会修改执行上下文（Execution Context）的作用域链，在最前面添加一个对象（Variable Object）。这就意味着在执行with的过程中，实际上的局部变量都被移到作用域链上的第二个位置，这会带来性能上的损失。<br />
* 如果你确定一段代码肯定会抛出异常，那么就要避免使用try-catch，因为catch分支在作用域链上的处理方法和with是一样的。但try分支的代码是没有性能损失的，所以还是建议用try-catch来捕获那些不可预知的错误。</p>
<p>如果你想围绕这个话题展开更多的讨论，我在上个月的<a href="http://javascript.meetup.com/9/">Mountain View JavaScript Meetup</a>中曾经发表了一个小演讲。可以在SlideShare上下载<a href="http://www.slideshare.net/nzakas/java-script-variable-performance-presentation">幻灯片</a>，或者观看聚会的<a href="http://www.youtube.com/watch?v=MHBbK9dt0Kg">完整视频</a>，我的演讲大概从11分钟左右时开始。</p>
<p>译者笔记</p>
<p>大家如果在阅读本文的过程中，有什么疑惑，建议延伸阅读以下两篇文章：<br />
* Richie写的《<a href="http://www.cnblogs.com/RicCC/archive/2008/02/15/javascript-object-model-execution-model.html">JavaScript对象模型-执行模型</a>》<br />
* 《<a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262第三版</a>》，主要看看第十章，就是执行上下文（Execution Context）那张，本文提到的名词在那里都有详细的解释。</p>
<p>在最后的时候，Nicholas提到一个Mountain View JavaScript Meetup，Meetup那个网站其实就是一个各种现实世界活动的组织网站，需要翻墙才能访问，住在California真幸福，有那么多的好活动可以参加，呵呵。</p>
]]></content:encoded>
			<wfw:commentRss>http://oragg.com/2009/06/javascript-variable-performance.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>浏览器根据什么来判定脚本失控？</title>
		<link>http://oragg.com/2009/02/what-determines-that-a-script-is-long-running.html</link>
		<comments>http://oragg.com/2009/02/what-determines-that-a-script-is-long-running.html#comments</comments>
		<pubDate>Sat, 14 Feb 2009 18:35:35 +0000</pubDate>
		<dc:creator>大蒜</dc:creator>
				<category><![CDATA[Translation]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Long-Running Script]]></category>
		<category><![CDATA[Runaway Script]]></category>

		<guid isPermaLink="false">http://oragg.com/?p=38</guid>
		<description><![CDATA[本文译自Nicholas C. Zakas于2009年1月5日在个人网站上发表的《What determines that a script is long-running?》。原文是唯一的正式版，本文是经过原文作者授权的简体中文翻译版。译者在翻译的准确性上做了大量的努力，并承诺译文的内容完全忠于原文，但可能还是包含疏漏和不妥之处，欢迎大家指正。译序和译注的内容是非正式的，仅代表译者个人观点。
译者序：在Web开发的时候，经常会遇到的一种情况就是浏览器提示脚本运行时间过长，停止还是继续，无论你选择什么，相信你都会想尽一切办法让这个对话框远离你的用户们。可你是否知道，这些不同的浏览器究竟是如何判断，哪些脚本处于“失控”状态么？本文作者，就从Internet Explorer、Firefox、Safari、Chrome和Opera五种浏览器，分析了这个情况出现的原因。
以下是对原文的翻译：
Web开发者经常遇到并必须及时处理的问题就是“提示脚本运行时间过长的提示框”（或者称为“失控脚本提示”），这些令人讨厌的对话框会在你的脚本 执行时间过长的时候出现。对于Web开发者的基本准则就是，无论什么时候，都不要让用户看到这些对话框，因为这会给人一种代码缺乏结构化的印象，更简单的说，你的代码负担太重了。
用Brendan Eich（JavaScript的发明人）的话来讲，如果JavaScript运行的时间需要用秒来计算，一定是什么地方搞错了。我个人可以忍受的上限可 能更小一些，不论什么脚本，在任何时间、任何浏览器上执行，都不应该超过100毫秒。如果实际执行的时间长于这个底限，一定要将进程分解成若干更小的代码段。
另外，其实很少有人真正意识到究竟是什么原因导致脚本在不同的浏览器中运行时间过长，连我自己都没有深究过。所以我决定坐下来好好研究一下，我们究竟会在什么情况才会看到那个讨厌的对话框。判断脚本是否失控，无外乎就两种方法。一种是根据执行了多少条语句，一种是判断脚本执行花费的时间。各个浏览器 判断脚本失控的具体方法会有略微的不同。
Internet Explorer
Internet Explorer判断一个脚本是否失控，主要通过JScript引擎执行语句的总数来判断。默认情况下，这个上限是500万条语句，这个值是可以通过注册表修改的。当你的脚本执行的语句数量超过这个限制，你就会看到下面的窗口。

这个对话框提示：“这个页面上有一段脚本导致Internet Explorer运行缓慢，如果你继续运行，你的计算机可能会变为无响应状态”。要不是追求技术上的准确性，这样说确实有点过了。对话框有两个选项，要么 停止脚本执行，要么允许脚本继续运行。当这个对话框显示的时候，脚本已经被完全停止了。如果你选择继续运行脚本，就会重新计算当前执行的语句数，也就是 说，如果这个数值再次达到上限时，你会再次看到这个对话框。
Firefox
Firefox是根据脚本引擎持续执行代码的时间来判断一段脚本是否失控。默认的上限是10秒，可以通过about:config页面来修改这个值。这里需要注意的是，当弹出类似alert的模式对话框的时候，是不计时的。当浏览器执行脚本的时间达到这个上限，Firefox就会显示类似下面的对话框：

Firefox的对话框提示：“这个页面的一段脚本目前运行忙，或者这段脚本已经停止响应。你可以停止执行这段脚本，并在调试器中打开这段脚本，或 者保持这段脚本继续运行”。更清楚的描述了遇到的问题，并且没有IE说的那么恐怖。在这个对话框上可以执行三种操作：停止脚本执行、调试脚本或者让脚本继 续运行。和Internet Explorer一样，当运行脚本继续运行以后，对持续运行脚本时间的统计就会重置。调试脚本按钮，只有在你安装了Firebug，并在该页面激活了调试 的时候才会出现。执行调试脚本操作后，可以显示执行时间过长的代码段的具体位置。
Safari
Safari同样根据脚本引擎持续执行脚本的时间来判断，当我对Webkit的源代码进行反复研究后，发现默认的超时时间是5秒，一旦达到这个上限，就会给出下面的对话框提示：

对话框提示：“在页面url上的脚本让Safari失去响应，你是要继续运行脚本还是终止脚本”。同样的，对于用户来说，也不是什么可怕的提示。在Safari中，可以关闭失控脚本的检测功能。
Chrome
Chrome在跟踪技术上有点狡猾，失控脚本检测功能似乎和tab的事故控制（crash control）关联到一起。我仔细看了源代码，却没有找到具体的限制，但基本确定的是，这个限制是以时间为基础的，估计在10秒左右（要么是5秒，要么 是10秒，总要和Safari或者Firefox看齐么）。我正在联系Chrome项目组中的朋友，看看能不能得到确定的信息。尽管如此，如果网页中存在 失控的脚本，用户还是会看到下面的对话框：

毫无疑问，Chrome的提示比起其他浏览器来说，显得都更加严重。点击“Wait”按钮，脚本会继续运行，直到达到下一个上限为止，也可以点击“Kill pages”，直接关闭该页面在内存中的所有信息，并用一个空白页取而代之。
Opera
Opera的情况比较有趣：他貌似没有针对失控脚本的相应限制。我运行了几个很长的测试，甚至花了几分钟，而在这个过程中，浏览器一直可以正常响应，这很出我的意料之外。我不是很确定，对于现在的情况来说，这个方法是好是坏，但至少它生效了，不是么？
一些建议
无论你的用户使用什么浏览器，都不应该在任何时候看到类似的提示。在你的网站或者Web应用程序作为产品发布之前，做一些常规的性能测试是非常有必要的。在这方面有很多工具可以加以利用，比如Firebug’s profiler（只支持Firefox）、YUI Profiler （支持全部浏览器）或者Internet Explorer 8’s Profiler。 你应该毫不犹豫地将那些执行时间超过100毫秒的脚本找出来，哪怕这些脚本只是在某些浏览器上运行不畅，这些脚本包含了一些需要执行很长时间的代码段，而 这些代码应该通过性能检测工具进行重新评估。确保你不是使用Chrome作为测试的底线，因为Chrome在执行JavaScript的速度上比其他浏览 器要高出一个数量级（和Firefox 3.1还有最新的WebKit Nightly相当）。最好使用Internet Explorer作为测试的底线，然后再测试其他浏览器，因为无论什么时候，IE的JavaScript引擎都是最慢的，当在IE上修复问题以后，十有八 九在其他浏览器上也可以正常运行了。
==== 本系列的所有文章 ====

浏览器根据什么来判定脚本失控？
如何提升JavaScript的运行速度（循环篇）
如何提升JavaScript的运行速度（函数篇）
如何提升JavaScript的运行速度（递归篇）
如何提升JavaScript的运行速度（DOM篇）

]]></description>
			<content:encoded><![CDATA[<p>本文译自<a href="http://www.nczonline.net/contact/">Nicholas C. Zakas</a>于2009年1月5日在<a href="http://www.nczonline.net/">个人网站</a>上发表的《<a href="http://www.nczonline.net/blog/2009/01/05/what-determines-that-a-script-is-long-running/" target="_blank">What determines that a script is long-running?</a>》。原文是唯一的正式版，本文是经过原文作者授权的简体中文翻译版。译者在翻译的准确性上做了大量的努力，并承诺译文的内容完全忠于原文，但可能还是包含疏漏和不妥之处，欢迎大家指正。译序和译注的内容是非正式的，仅代表译者个人观点。</p>
<p>译者序：在Web开发的时候，经常会遇到的一种情况就是浏览器提示脚本运行时间过长，停止还是继续，无论你选择什么，相信你都会想尽一切办法让这个对话框远离你的用户们。可你是否知道，这些不同的浏览器究竟是如何判断，哪些脚本处于“失控”状态么？本文作者，就从Internet Explorer、Firefox、Safari、Chrome和Opera五种浏览器，分析了这个情况出现的原因。</p>
<p>以下是对原文的翻译：</p>
<p>Web开发者经常遇到并必须及时处理的问题就是“提示脚本运行时间过长的提示框”（或者称为“失控脚本提示”），这些令人讨厌的对话框会在你的脚本 执行时间过长的时候出现。对于Web开发者的基本准则就是，无论什么时候，都不要让用户看到这些对话框，因为这会给人一种代码缺乏结构化的印象，更简单的说，你的代码负担太重了。</p>
<p>用Brendan Eich（JavaScript的发明人）的话来讲，如果JavaScript运行的时间需要用秒来计算，一定是什么地方搞错了。我个人可以忍受的上限可 能更小一些，不论什么脚本，在任何时间、任何浏览器上执行，都不应该超过100毫秒。如果实际执行的时间长于这个底限，一定要将进程分解成若干更小的代码段。</p>
<p>另外，其实很少有人真正意识到究竟是什么原因导致脚本在不同的浏览器中运行时间过长，连我自己都没有深究过。所以我决定坐下来好好研究一下，我们究竟会在什么情况才会看到那个讨厌的对话框。判断脚本是否失控，无外乎就两种方法。一种是根据执行了多少条语句，一种是判断脚本执行花费的时间。各个浏览器 判断脚本失控的具体方法会有略微的不同。</p>
<p>Internet Explorer</p>
<p>Internet Explorer判断一个脚本是否失控，主要通过JScript引擎执行语句的总数来判断。默认情况下，这个上限是500万条语句，这个值是可以<a href="http://support.microsoft.com/kb/175500">通过注册表修改</a>的。当你的脚本执行的语句数量超过这个限制，你就会看到下面的窗口。</p>
<p><a href="http://www.nczonline.net/blog/wp-content/uploads/2009/01/ie_dialog.png"><img title="IE Long-Running Script Dialog" src="http://www.nczonline.net/blog/wp-content/uploads/2009/01/ie_dialog-300x133.png" alt="IE Dialog: A script on this page is causing Internet Explorer to run slowly. If it continues to run, your compute may become unresponsive." width="300" height="133" /></a></p>
<p>这个对话框提示：“这个页面上有一段脚本导致Internet Explorer运行缓慢，如果你继续运行，你的计算机可能会变为无响应状态”。要不是追求技术上的准确性，这样说确实有点过了。对话框有两个选项，要么 停止脚本执行，要么允许脚本继续运行。当这个对话框显示的时候，脚本已经被完全停止了。如果你选择继续运行脚本，就会重新计算当前执行的语句数，也就是 说，如果这个数值再次达到上限时，你会再次看到这个对话框。</p>
<p>Firefox</p>
<p>Firefox是根据脚本引擎持续执行代码的时间来判断一段脚本是否失控。默认的上限是10秒，可以<a href="http://kb.mozillazine.org/Dom.max_script_run_time">通过about:config页面来修改这个值</a>。这里需要注意的是，当弹出类似alert的模式对话框的时候，是不计时的。当浏览器执行脚本的时间达到这个上限，Firefox就会显示类似下面的对话框：</p>
<p><a href="http://www.nczonline.net/blog/wp-content/uploads/2009/01/firefox_dialog.png"><img title="Firefox Long-Running Script Dialog" src="http://www.nczonline.net/blog/wp-content/uploads/2009/01/firefox_dialog-300x80.png" alt="Firefox Dialog: A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue." width="300" height="80" /></a></p>
<p>Firefox的对话框提示：“这个页面的一段脚本目前运行忙，或者这段脚本已经停止响应。你可以停止执行这段脚本，并在调试器中打开这段脚本，或 者保持这段脚本继续运行”。更清楚的描述了遇到的问题，并且没有IE说的那么恐怖。在这个对话框上可以执行三种操作：停止脚本执行、调试脚本或者让脚本继 续运行。和Internet Explorer一样，当运行脚本继续运行以后，对持续运行脚本时间的统计就会重置。调试脚本按钮，只有在你安装了Firebug，并在该页面激活了调试 的时候才会出现。执行调试脚本操作后，可以显示执行时间过长的代码段的具体位置。</p>
<p>Safari</p>
<p>Safari同样根据脚本引擎持续执行脚本的时间来判断，当我对<a href="http://trac.webkit.org/changeset/14904#file4">Webkit的源代码</a>进行反复研究后，发现默认的超时时间是5秒，一旦达到这个上限，就会给出下面的对话框提示：</p>
<p><a href="http://www.nczonline.net/blog/wp-content/uploads/2009/01/safari_dialog.png"><img title="Safari Long-Running Script Dialog" src="http://www.nczonline.net/blog/wp-content/uploads/2009/01/safari_dialog-300x130.png" alt="Safari Dialog: A script on the page [url] is making Safari unresponsive. Do you want to continue running the script, or stop it?" width="300" height="130" /></a></p>
<p>对话框提示：“在页面url上的脚本让Safari失去响应，你是要继续运行脚本还是终止脚本”。同样的，对于用户来说，也不是什么可怕的提示。在Safari中，可以<a href="http://developer.apple.com/DOCUMENTATION/AppleApplications/Conceptual/Safari_Developer_Guide/2SafariDeveloperTools/chapter_2_section_3.html#//apple_ref/doc/uid/TP40007874-CH3-DontLinkElementID_15">关闭失控脚本的检测功能</a>。</p>
<p>Chrome</p>
<p>Chrome在跟踪技术上有点狡猾，失控脚本检测功能似乎和tab的事故控制（crash control）关联到一起。我仔细看了源代码，却没有找到具体的限制，但基本确定的是，这个限制是以时间为基础的，估计在10秒左右（要么是5秒，要么 是10秒，总要和Safari或者Firefox看齐么）。我正在联系Chrome项目组中的朋友，看看能不能得到确定的信息。尽管如此，如果网页中存在 失控的脚本，用户还是会看到下面的对话框：</p>
<p><a href="http://www.nczonline.net/blog/wp-content/uploads/2009/01/chrome_dialog.png"><img title="Chrome Long-Running Script Dialog" src="http://www.nczonline.net/blog/wp-content/uploads/2009/01/chrome_dialog-300x171.png" alt="Chrome Dialog: The following page(s) have become unresponsive. You can wait for them to become responsive or kill them." width="300" height="171" /></a></p>
<p>毫无疑问，Chrome的提示比起其他浏览器来说，显得都更加严重。点击“Wait”按钮，脚本会继续运行，直到达到下一个上限为止，也可以点击“Kill pages”，直接关闭该页面在内存中的所有信息，并用一个空白页取而代之。</p>
<p>Opera</p>
<p>Opera的情况比较有趣：他貌似没有针对失控脚本的相应限制。我运行了几个很长的测试，甚至花了几分钟，而在这个过程中，浏览器一直可以正常响应，这很出我的意料之外。我不是很确定，对于现在的情况来说，这个方法是好是坏，但至少它生效了，不是么？</p>
<p>一些建议</p>
<p>无论你的用户使用什么浏览器，都不应该在任何时候看到类似的提示。在你的网站或者Web应用程序作为产品发布之前，做一些常规的性能测试是非常有必要的。在这方面有很多工具可以加以利用，比如<a href="http://getfirebug.com/js.html">Firebug’s profiler</a>（只支持Firefox）、<a href="http://developer.yahoo.com/yui/profiler/">YUI Profiler</a> （支持全部浏览器）或者<a href="http://msdn.microsoft.com/en-us/library/cc848895%28VS.85%29.aspx">Internet Explorer 8’s Profiler</a>。 你应该毫不犹豫地将那些执行时间超过100毫秒的脚本找出来，哪怕这些脚本只是在某些浏览器上运行不畅，这些脚本包含了一些需要执行很长时间的代码段，而 这些代码应该通过性能检测工具进行重新评估。确保你不是使用Chrome作为测试的底线，因为Chrome在执行JavaScript的速度上比其他浏览 器要高出一个数量级（和Firefox 3.1还有最新的WebKit Nightly相当）。最好使用Internet Explorer作为测试的底线，然后再测试其他浏览器，因为无论什么时候，IE的JavaScript引擎都是最慢的，当在IE上修复问题以后，十有八 九在其他浏览器上也可以正常运行了。</p>
<p>==== 本系列的所有文章 ====</p>
<ul>
<li><a href="http://oragg.com/2009/02/what-determines-that-a-script-is-long-running.html">浏览器根据什么来判定脚本失控？</a></li>
<li><a href="http://oragg.com/2009/02/speed-up-your-javascript-part-1.html">如何提升JavaScript的运行速度（循环篇）</a></li>
<li><a href="http://oragg.com/2009/02/speed-up-your-javascript-part-2.html">如何提升JavaScript的运行速度（函数篇）</a></li>
<li><a href="http://oragg.com/2009/02/speed-up-your-javascript-part-3.html">如何提升JavaScript的运行速度（递归篇）</a></li>
<li><a href="http://oragg.com/2009/02/speed-up-your-javascript-part-4.html">如何提升JavaScript的运行速度（DOM篇）</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://oragg.com/2009/02/what-determines-that-a-script-is-long-running.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
