<?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/"
	>

<channel>
	<title>Belltoy's blog</title>
	<atom:link href="http://blog.belltoy.net/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.belltoy.net</link>
	<description>Don't panic!</description>
	<pubDate>Sat, 06 Mar 2010 09:02:23 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>2009年总结</title>
		<link>http://blog.belltoy.net/summary-of-2009.html</link>
		<comments>http://blog.belltoy.net/summary-of-2009.html#comments</comments>
		<pubDate>Thu, 21 Jan 2010 17:27:18 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[日志]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=336</guid>
		<description><![CDATA[2010年1月8日从上海搬来杭州到现在，已经将近两周时间了。来之前，因为公司手续和房子合约的问题，弄得很不愉快。来之后，因为一边找房子一边上班，也没什么时间。上周末刚搬到新的住外，总算可以静下心了，总结一下已经过去的2009年。
2009 年上半年可以说是风调雨顺。不管是工作、学习还是生活上，感觉都很充实，还把团队的气氛带起来了。杯具的转折点在7月份前后出现了。由于公司人事上出了比较严重的漏洞，导致项目停滞，士气大降。我当时选择了离开（后来松果团队纠正了那次的问题，不过我还是没打算再回去）。下半年就在上海漂了，找过几家公司，都挺不靠谱的。这段时间里状态一直都不好，特别是当一个人失业时间长了，那种失落感会与日俱增。甚至出现过“回老家吃老本”的念头。
好在有两个人，让我坚持了自己了方向。9月份的时候，博文视点的周筠老师让我写一篇《程序员修炼之道》的书评。当时又读了一遍这本书，还有几位前辈对这本书的书评，激动了，淡定了。继续学习和积累吧，我还年轻，要学的东西太多了。之后周老师还帮我介绍工作职位，这着实让我很感动。另一位是冯大辉老师，他帮我推荐了好几次简历。有一次淘宝的面试机会，可惜我没发挥好，他还是给我肯定和鼓励。现在加入 Yupoo 也是冯老师的推荐。我真的很感谢他们，还有关心帮助过我的朋友。
CCAV 老说网络是妖魔，充满了低俗与虚假，天朝警察说他肚子痛关你什么事。都见鬼去吧！在网络与现实中，还是有不少真诚相待的朋友的。
在松果团队的时候，参与了 Webgame 的设计和开发，后来还做了些性能调优的工作。我也因此接触到了很多关于高性能 Web 系统的知识。虽然实践还不多，但这些知识还是 Web 开发中必备的。学习别人的经验也算是一种积累吧。
前端部分，在对 Javascript 语言特性作了进一步的了解，理解了闭包、作用域链和函数调用对象这几个概念之后，我才算是对 Javascript 语言有了一个比较深刻的体会。这也对我后来学习其它具有函数式特性的语言时有很大的帮助。YUI 的前端优化建议也做了一些实践。CSS 一直是我的死穴，可能是我对界面的东西不那么感兴趣的缘故吧。
PHP 新的东西就不多了，主要是学习了 PHP 系统常用的设计方法，比如 ThinkPHP 和 Codeigniter 框架的设计。更多的是了解了 HTTP 协议中常用的部分，前端优化也有涉及到 HTTP 协议。读了 《RESTful WebService》，感觉 REST 这种设计方式很容易接受，可能是符合标准的关系吧。
读了一本关于数据库的书《MySQL性能调优与架构设计》，主要讲的是数据库系统的性能调优和高可用可扩展的架构设计。另外看了一些 Web 系统的架构设计和 Cache 的应用的案例，比如豆瓣、twitter。关于这些方面，实践太少，希望能有机会介入到相关的工作实践中。
从C10K，到了解事件模型和异步I/O的技术，我发现计算机专业基础值得复习和深入学习。包括算法，操作系统，编译原理，网络编程的书，我都将它们列入了今年的读书计划中。
去年还花了点时间看了 Python 的语法，现在工作中要用到了，正好可以深入研究一下。
在去年下半年比较空闲的时间里，看了很多经典的老片，这也算是一种收获吧。另外，2009年翻墙成了我日常网络生活中的一部分，也因此了解了比较真实的世界。纳美人认为，人的一生有两次生命，第一次是出生，第二次是建立起属于自己的社会地位。我也有两次生命，第一次是出生，第二次是翻墙之后。
-EOF-
随机文章

通过SMTP发送邮件
评论《程序员修炼之道:从小工到专家》
强大的图形思维工具——思维导图
从总结中学习
Oracle 查询优化

]]></description>
			<content:encoded><![CDATA[<p>2010年1月8日从上海搬来杭州到现在，已经将近两周时间了。来之前，因为公司手续和房子合约的问题，弄得很不愉快。来之后，因为一边找房子一边上班，也没什么时间。上周末刚搬到新的住外，总算可以静下心了，总结一下已经过去的2009年。</p>
<p>2009 年上半年可以说是风调雨顺。不管是工作、学习还是生活上，感觉都很充实，还把团队的气氛带起来了。杯具的转折点在7月份前后出现了。由于公司人事上出了比较严重的漏洞，导致项目停滞，士气大降。我当时选择了离开（后来松果团队纠正了那次的问题，不过我还是没打算再回去）。下半年就在上海漂了，找过几家公司，都挺不靠谱的。这段时间里状态一直都不好，特别是当一个人失业时间长了，那种失落感会与日俱增。甚至出现过“回老家吃老本”的念头。</p>
<p>好在有两个人，让我坚持了自己了方向。9月份的时候，博文视点的周筠老师让我写一篇《程序员修炼之道》的书评。当时又读了一遍这本书，还有几位前辈对这本书的书评，激动了，淡定了。继续学习和积累吧，我还年轻，要学的东西太多了。之后周老师还帮我介绍工作职位，这着实让我很感动。另一位是冯大辉老师，他帮我推荐了好几次简历。有一次淘宝的面试机会，可惜我没发挥好，他还是给我肯定和鼓励。现在加入 Yupoo 也是冯老师的推荐。我真的很感谢他们，还有关心帮助过我的朋友。</p>
<p>CCAV 老说网络是妖魔，充满了低俗与虚假，天朝警察说他肚子痛关你什么事。都见鬼去吧！在网络与现实中，还是有不少真诚相待的朋友的。</p>
<p>在松果团队的时候，参与了 Webgame 的设计和开发，后来还做了些性能调优的工作。我也因此接触到了很多关于高性能 Web 系统的知识。虽然实践还不多，但这些知识还是 Web 开发中必备的。学习别人的经验也算是一种积累吧。</p>
<p>前端部分，在对 Javascript 语言特性作了进一步的了解，理解了闭包、作用域链和函数调用对象这几个概念之后，我才算是对 Javascript 语言有了一个比较深刻的体会。这也对我后来学习其它具有函数式特性的语言时有很大的帮助。YUI 的前端优化建议也做了一些实践。CSS 一直是我的死穴，可能是我对界面的东西不那么感兴趣的缘故吧。</p>
<p>PHP 新的东西就不多了，主要是学习了 PHP 系统常用的设计方法，比如 ThinkPHP 和 Codeigniter 框架的设计。更多的是了解了 HTTP 协议中常用的部分，前端优化也有涉及到 HTTP 协议。读了 《RESTful WebService》，感觉 REST 这种设计方式很容易接受，可能是符合标准的关系吧。</p>
<p>读了一本关于数据库的书《MySQL性能调优与架构设计》，主要讲的是数据库系统的性能调优和高可用可扩展的架构设计。另外看了一些 Web 系统的架构设计和 Cache 的应用的案例，比如豆瓣、twitter。关于这些方面，实践太少，希望能有机会介入到相关的工作实践中。</p>
<p>从C10K，到了解事件模型和异步I/O的技术，我发现计算机专业基础值得复习和深入学习。包括算法，操作系统，编译原理，网络编程的书，我都将它们列入了今年的读书计划中。</p>
<p>去年还花了点时间看了 Python 的语法，现在工作中要用到了，正好可以深入研究一下。</p>
<p>在去年下半年比较空闲的时间里，看了很多经典的老片，这也算是一种收获吧。另外，2009年翻墙成了我日常网络生活中的一部分，也因此了解了比较真实的世界。纳美人认为，人的一生有两次生命，第一次是出生，第二次是建立起属于自己的社会地位。我也有两次生命，第一次是出生，第二次是翻墙之后。</p>
<p>-EOF-<br />
<h3>随机文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/recently.html" title="最近">最近</a></li>
<li><a href="http://blog.belltoy.net/fix-java-swing-on-linux.html" title="linux下 java swing 问题的解决">linux下 java swing 问题的解决</a></li>
<li><a href="http://blog.belltoy.net/notes-of-download-files-impletment-with-jsp.html" title="JSP实现文件下载应注意的几个问题">JSP实现文件下载应注意的几个问题</a></li>
<li><a href="http://blog.belltoy.net/take_care_of_source_files_encoding.html" title="源代码的字符集不同带来的问题">源代码的字符集不同带来的问题</a></li>
<li><a href="http://blog.belltoy.net/oracle-sql-optimize.html" title="Oracle 查询优化">Oracle 查询优化</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/summary-of-2009.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Happy New Year !</title>
		<link>http://blog.belltoy.net/happy-new-year-2010.html</link>
		<comments>http://blog.belltoy.net/happy-new-year-2010.html#comments</comments>
		<pubDate>Thu, 31 Dec 2009 15:59:43 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[未分类]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=334</guid>
		<description><![CDATA[这几天看到大家都在写总结，自己却因为一些事在折腾。
在2009年的最后一刻，先留下一个祝福，祝福所有认识的和不认识的朋友，还有自己：
Happy New Year !
稍后补上年度总结。
-EOF-
随机文章

强大的图形思维工具——思维导图
Oracle 查询优化
2008年终总结
perl发邮件脚本
终于拿到大骆驼了

]]></description>
			<content:encoded><![CDATA[<p>这几天看到大家都在写总结，自己却因为一些事在折腾。<br />
在2009年的最后一刻，先留下一个祝福，祝福所有认识的和不认识的朋友，还有自己：</p>
<p style="font-size:1.5em;">Happy New Year !</p>
<p>稍后补上年度总结。</p>
<p>-EOF-<br />
<h3>随机文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/hello-world.html" title="Hello World!">Hello World!</a></li>
<li><a href="http://blog.belltoy.net/want_to_study_sign_language.html" title="我想学手语">我想学手语</a></li>
<li><a href="http://blog.belltoy.net/notes-of-gzip-compression.html" title="HTTP 输出 Gzip 的注意事项">HTTP 输出 Gzip 的注意事项</a></li>
<li><a href="http://blog.belltoy.net/talk-about-overtime.html" title="说说关于加班">说说关于加班</a></li>
<li><a href="http://blog.belltoy.net/summary-of-2008.html" title="2008年终总结">2008年终总结</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/happy-new-year-2010.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>apache2 和 tomcat5.5 集成及虚拟主机配置</title>
		<link>http://blog.belltoy.net/howto-config-virtualhost-with-apache-and-tomcat-on-ubuntu.html</link>
		<comments>http://blog.belltoy.net/howto-config-virtualhost-with-apache-and-tomcat-on-ubuntu.html#comments</comments>
		<pubDate>Wed, 25 Nov 2009 16:51:04 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[apache]]></category>

		<category><![CDATA[jsp]]></category>

		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=308</guid>
		<description><![CDATA[想起以前 tomcat 还没配过虚拟主机，便想试试，就随手集成了 apache2。把配置过程记录在这里。
安装 apache2、JDK、tomcat 就不写了，查看文档吧。
apache2 要整合 tomcat 需要用到 mod_jk。Ubuntu 下安装 mod_jk 很简单：

$ sudo apt-get install libapache2-mod-jk

可以查看一下这个包安装后产生的配置文件：

$ dpkg -L libapache2-mod-jk


1
2
3
4
5
6
7
8
......
/etc
/etc/libapache2-mod-jk
/etc/libapache2-mod-jk/workers.properties
/etc/apache2
/etc/apache2/mods-available
/etc/apache2/mods-available/jk.load
......


配置 workers.properties 文件，修改其中的 workers.tomcat_home 和 workers.java_home 字段，改成正确的路径。例如，我的：

1
2
workers.tomcat_home = /home/belltoy/dev/apache-tomcat-5.5.25/
workers.java_home = /opt/jdk1.6.0_05/

workers.properties 文件默认已经配置了一个 worker，名字是 ajp13_worker，如下：

1
2
3
4
5
6
7
8
worker.list=ajp13_worker
worker.ajp13_worker.port=8009       #tomcat默认开了8009商品。根据实际情况适当修改。
worker.ajp13_worker.host=localhost  #tomcat服务器所在的主机
worker.ajp13_worker.type=ajp13      #apache2 连接 tomcat 的协议，默认为 ajp13
worker.ajp13_worker.lbfactor=1    [...]]]></description>
			<content:encoded><![CDATA[<p>想起以前 tomcat 还没配过虚拟主机，便想试试，就随手集成了 apache2。把配置过程记录在这里。</p>
<p>安装 apache2、JDK、tomcat 就不写了，查看文档吧。</p>
<p>apache2 要整合 tomcat 需要用到 mod_jk。Ubuntu 下安装 mod_jk 很简单：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libapache2-mod-jk</pre></div></div>

<p>可以查看一下这个包安装后产生的配置文件：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">-L</span> libapache2-mod-jk</pre></div></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">......
<span style="color: #000000; font-weight: bold;">/</span>etc
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>libapache2-mod-jk
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>libapache2-mod-jk<span style="color: #000000; font-weight: bold;">/</span>workers.properties
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apache2
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>mods-available
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>mods-available<span style="color: #000000; font-weight: bold;">/</span>jk.load
......</pre></td></tr></table></div>

<p><span id="more-308"></span></p>
<p>配置 workers.properties 文件，修改其中的 workers.tomcat_home 和 workers.java_home 字段，改成正确的路径。例如，我的：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">workers.tomcat_home = <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>belltoy<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>apache-tomcat-5.5.25<span style="color: #000000; font-weight: bold;">/</span>
workers.java_home = <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>jdk1.6.0_05<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

<p>workers.properties 文件默认已经配置了一个 worker，名字是 ajp13_worker，如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">worker.list=ajp13_worker
worker.ajp13_worker.port=<span style="color: #000000;">8009</span>       <span style="color: #666666; font-style: italic;">#tomcat默认开了8009商品。根据实际情况适当修改。</span>
worker.ajp13_worker.host=localhost  <span style="color: #666666; font-style: italic;">#tomcat服务器所在的主机</span>
worker.ajp13_worker.type=ajp13      <span style="color: #666666; font-style: italic;">#apache2 连接 tomcat 的协议，默认为 ajp13</span>
worker.ajp13_worker.lbfactor=<span style="color: #000000;">1</span>      <span style="color: #666666; font-style: italic;">#负载均衡选项。</span>
&nbsp;
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=ajp13_worker</pre></td></tr></table></div>

<p>在 /etc/apache2/mods-available 目录下增加一个文件 jk.conf，内容如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">JkWorkersFile <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>libapache2-mod-jk<span style="color: #000000; font-weight: bold;">/</span>workers.properties  <span style="color: #666666; font-style: italic;">#指定 mod_jk 的workers.properties 文件的位置</span>
JkLogFile <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>mod_jk.log  <span style="color: #666666; font-style: italic;"># 指定mod_jk的日志文件位置</span>
JkLogLevel info   <span style="color: #666666; font-style: italic;"># 指定od_jk的日志级别</span>
JkLogStampFormat <span style="color: #ff0000;">&quot;[%a %b %d %H:%M:%S %Y]&quot;</span>  <span style="color: #666666; font-style: italic;"># 指定od_jk的日志格式</span>
JkOptions +ForwardKeySize +ForwardURICompat <span style="color: #660033;">-ForwardDirectories</span>  <span style="color: #666666; font-style: italic;"># 指定od_jk的选项</span>
JkRequestLogFormat <span style="color: #ff0000;">&quot;%w %V %T&quot;</span> <span style="color: #666666; font-style: italic;"># 指定od_jk的请求日志格式，也是写在JkLogFile文件里</span></pre></td></tr></table></div>

<p>然后先禁用 mod_jk，再重新启用，这样 Ubuntu 自带的 apache2 工具会自动将 jk.conf 也放到启用目录 /etc/apache2/mods-enabled/ 下。命令：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> a2dismod jk
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> a2enmod jk</pre></div></div>

<p>假设虚拟主机名取为 jspproj.belltoy。</p>
<p>在 /etc/hosts 文件中添加本地主机名：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">127.0.0.1        jspproj.belltoy</pre></div></div>

<p>添加 apache2 下的虚拟主机配置</p>
<p>在 /etc/apache2/sites-available 目录下添加一个虚拟主机配置。配置如下：</p>
<p>文件名可以随便取，如：jspproj</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;VirtualHost</span> *<span style="color: #000000; font-weight: bold;">&gt;</span></span>
    # 匹配的URL将转给 tomcat 处理
    JkMount /servlet/* ajp13_worker
    JkMount /*.jsp ajp13_worker
    JkMount /*.do ajp13_worker
    JkMount /* ajp13_worker
&nbsp;
    ServerAdmin admin@localhost
    ServerName  jspproj.belltoy
    CustomLog   /var/log/apache2/jspproj.belltoy-access.log combined
    DocumentRoot /home/belltoy/www/jspproj/
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Directory</span> /home/belltoy/www/jspproj<span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        allow from all
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Directory<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/VirtualHost<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>启用jspproj:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> a2ensite jspproj</pre></div></div>

<p>重新启动 apache2:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 restart</pre></div></div>

<p>配置 tomcat5.5</p>
<p>在 tomcat 安装目录的 conf/server.xml 文件中 &lt;Engine&gt; 里增加一个虚拟主机的配置：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;">      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Host</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;jspproj.belltoy&quot;</span> <span style="color: #000066;">appBase</span>=<span style="color: #ff0000;">&quot;/home/belltoy/www/jspproj/&quot;</span> </span>
<span style="color: #009900;">            <span style="color: #000066;">unpackWARs</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">autoDeploy</span>=<span style="color: #ff0000;">&quot;true&quot;</span></span>
<span style="color: #009900;">            <span style="color: #000066;">xmlValidation</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000066;">xmlNamespaceAware</span>=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Context</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">docBase</span>=<span style="color: #ff0000;">&quot;/home/belltoy/www/jspproj/&quot;</span></span>
<span style="color: #009900;">                <span style="color: #000066;">reloadable</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">crossContext</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Host<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>启动 tomcat，在浏览器访问 http://jspproj.belltoy/ 就可以访问 /home/belltoy/www/jspproj/ 目录下的 jsp 应用了。</p>
<p>在jsp的概念中，一个主机&lt;Host&gt;下可以有多个 webapp，默认的 webapp 就是 path 为空的 &lt;Context&gt; 指定的目录。如果这里不指定 path 为空的&lt;Context&gt;，tomcat默认会用 appBase 指定的目录下的 ROOT 目录作为默认的 webapp。</p>
<h3>相关文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/notes-of-gzip-compression.html" title="HTTP 输出 Gzip 的注意事项">HTTP 输出 Gzip 的注意事项</a></li>
<li><a href="http://blog.belltoy.net/take_care_of_source_files_encoding.html" title="源代码的字符集不同带来的问题">源代码的字符集不同带来的问题</a></li>
<li><a href="http://blog.belltoy.net/pathinfo-of-thinkphp-effect-on-site-performance.html" title="ThinkPHP 框架的 PATHINFO 模式对站点性能的影响">ThinkPHP 框架的 PATHINFO 模式对站点性能的影响</a></li>
<li><a href="http://blog.belltoy.net/summary-of-2008.html" title="2008年终总结">2008年终总结</a></li>
<li><a href="http://blog.belltoy.net/css-div-is-not-standard-layout.html" title="CSS+DIV不是标准布局">CSS+DIV不是标准布局</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/howto-config-virtualhost-with-apache-and-tomcat-on-ubuntu.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>新的封面</title>
		<link>http://blog.belltoy.net/new-cover.html</link>
		<comments>http://blog.belltoy.net/new-cover.html#comments</comments>
		<pubDate>Tue, 08 Sep 2009 13:19:32 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Other]]></category>

		<category><![CDATA[book]]></category>

		<category><![CDATA[programmer]]></category>

		<category><![CDATA[程序员]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=280</guid>
		<description><![CDATA[收到消息，《程序员修炼之道》这本书的中文新版已经送印了，应该很快就要出来了。
感谢编辑给我发来了新书的新封面。与上一版中文的封面不同，这次基本采用了原版的封面设计，加上中文的一些介绍。
原来网易、趋势科技这些公司的新员工培训就用了这本书，这印证了我之前的想法。
另外，云风、霍炬、徐宥等几位高手都是我十分敬仰的技术大牛。
再一次感谢周老师的邀请，让我这个菜鸟也有机会和大牛们一起为这本经典之作写书评。同时，也感谢博文视点的各位编辑。

-EOF-
相关文章

评论《程序员修炼之道:从小工到专家》
《程序员修炼之道》书评
终于拿到大骆驼了

]]></description>
			<content:encoded><![CDATA[<div id="attachment_281" class="wp-caption alignleft" style="width: 123px"><a href="http://blog.belltoy.net/wp-content/uploads/2009/09/new_cover.jpg"><img class="size-medium wp-image-281" title="程序员修炼之道" src="http://blog.belltoy.net/wp-content/uploads/2009/09/new_cover-226x300.jpg" alt="《程序员修炼之道》封面" width="113" height="150" /></a><p class="wp-caption-text">《程序员修炼之道》封面</p></div>
<p>收到消息，《程序员修炼之道》这本书的中文新版已经送印了，应该很快就要出来了。</p>
<p>感谢编辑给我发来了新书的新封面。与上一版中文的封面不同，这次基本采用了原版的封面设计，加上中文的一些介绍。</p>
<p>原来网易、趋势科技这些公司的新员工培训就用了这本书，这印证了我之前的想法。</p>
<p>另外，云风、霍炬、徐宥等几位高手都是我十分敬仰的技术大牛。</p>
<p>再一次感谢<a href="http://yeka.blogbus.com/">周老师</a>的邀请，让我这个菜鸟也有机会和大牛们一起为这本经典之作写书评。同时，也感谢博文视点的各位编辑。</p>
<p><span id="more-280"></span></p>
<p>-EOF-<br />
<h3>相关文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/read-the-pragmatic-programmer.html" title="评论《程序员修炼之道:从小工到专家》">评论《程序员修炼之道:从小工到专家》</a></li>
<li><a href="http://blog.belltoy.net/reveiw-the-pragmatic-programmer.html" title="《程序员修炼之道》书评">《程序员修炼之道》书评</a></li>
<li><a href="http://blog.belltoy.net/fetch-programming-perl-3rd-cn.html" title="终于拿到大骆驼了">终于拿到大骆驼了</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/new-cover.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>HTTP 输出 Gzip 的注意事项</title>
		<link>http://blog.belltoy.net/notes-of-gzip-compression.html</link>
		<comments>http://blog.belltoy.net/notes-of-gzip-compression.html#comments</comments>
		<pubDate>Tue, 25 Aug 2009 15:24:45 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[Optimize]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=267</guid>
		<description><![CDATA[昨天上 Jobsdigg.com 发现 Firebug 里飘红，于是做了一些测试，在这里做个笔记。
如今海量存储已经不是问题，反而是带宽资源有限，成了 Web 应用中主要瓶颈的所在。因此减少响应的传输量也就成了优化的关键。
Yahoo 的 34 条前端优化规则 中提到了 Gzip 压缩，Google 的前端性能最佳实践 中也提到了 Gzip 压缩。把服务器响应中的文本内容用 Gzip 压缩后可以减少大约 70％ 的大小。这着实对前端性能和用户体验的提升有明显的帮助。
从 HTTP/1.1 开始，客户端就可以在请求头中添加

 Accept-Encoding: gzip,deflate

来向请求的服务器表明自己支持 Gzip 压缩的响应。Web 服务器则在响应头中添加

 Content-Encoding: gzip

来向客户端表明响应体是经过 gzip 压缩的。

Apache不同版本使用的模块不同，在 Apache1.3 用的是 mod_gzip 模块，而 Apache2.x 用的是 mod_deflate 模块。用支持压缩的服务器来配置 Gzip 压缩输出是很方便的，它会自动在响应头中添加 Content-Encoding: gzip。
在服务器不支持对响应做 Gzip 压缩的情况下，我们可以事先用 gzip 命令把静态文件（如 js/css/xml/html 等文本内容）进行压缩。但 Web 服务器不会自动在响应头中添加 Content-Encoding: gzip ，必须手动为压缩过的文件添加这个响应头。如果服务器输出的是经过 [...]]]></description>
			<content:encoded><![CDATA[<p>昨天上 <a href="http://www.jobsdigg.com/" title="Jobs Digg">Jobsdigg.com</a> 发现 Firebug 里飘红，于是做了一些测试，在这里做个笔记。</p>
<p>如今海量存储已经不是问题，反而是带宽资源有限，成了 Web 应用中主要瓶颈的所在。因此减少响应的传输量也就成了优化的关键。</p>
<p><a href="http://developer.yahoo.com/performance/rules.html" title="Best Practices for Speeding Up Your Web Site">Yahoo 的 34 条前端优化规则</a> 中提到了 Gzip 压缩，<a href="http://code.google.com/speed/page-speed/docs/payload.html#GzipCompression" title="Enable gzip compression">Google 的前端性能最佳实践</a> 中也提到了 Gzip 压缩。把服务器响应中的文本内容用 Gzip 压缩后可以减少大约 70％ 的大小。这着实对前端性能和用户体验的提升有明显的帮助。</p>
<p>从 HTTP/1.1 开始，客户端就可以在请求头中添加</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"> Accept-Encoding: gzip,deflate</pre></div></div>

<p>来向请求的服务器表明自己支持 Gzip 压缩的响应。Web 服务器则在响应头中添加</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;"> Content-Encoding: gzip</pre></div></div>

<p>来向客户端表明响应体是经过 gzip 压缩的。</p>
<p><span id="more-267"></span></p>
<p>Apache不同版本使用的模块不同，在 Apache1.3 用的是 mod_gzip 模块，而 Apache2.x 用的是 mod_deflate 模块。用支持压缩的服务器来配置 Gzip 压缩输出是很方便的，它会自动在响应头中添加 Content-Encoding: gzip。</p>
<p>在服务器不支持对响应做 Gzip 压缩的情况下，我们可以事先用 gzip 命令把静态文件（如 js/css/xml/html 等文本内容）进行压缩。但 Web 服务器不会自动在响应头中添加 Content-Encoding: gzip ，必须手动为压缩过的文件添加这个响应头。如果服务器输出的是经过 Gzip 压缩过的内容而响应头中又没有 Content-Encoding 的声明，大多数浏览器不会正确识别响应体，Google Chrome 是个特例。</p>
<p>gzip 命令产生的文件默认是以 .gz 为后缀名的，比如</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"> ~$ <span style="color: #c20cb9; font-weight: bold;">gzip</span> jquery.js</pre></div></div>

<p>命令输出的就是 jquery.js.gz 文件。一般情况下，浏览器都是以 MIME 来识别响应类型，而不会以后缀名来识别。所以我们把这些静态文件经过手动的 gzip 压缩，把链接请求改成 .gz 的后缀，只要正确声明了 Content-Encoding 就不会有问题，但 Google Chrome 是个特例。 我做了个测试：</p>
<table border="1">
<thead>
<tr>
<td></td>
<td>Firefox 3.0</td>
<td>IE 6</td>
<td>Google Chrome 2.0</td>
</tr>
</thead>
<tbody>
<tr>
<td>未压缩的 js，后缀名 .js</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
<tr>
<td>压缩的 js，后缀名 .js，不加 Content-Encoding 声明</td>
<td>×</td>
<td>×</td>
<td>√</td>
</tr>
<tr>
<td>压缩的 js，后缀名 .js.gz，不加 Content-Encoding 声明</td>
<td>×</td>
<td>×</td>
<td>×</td>
</tr>
<tr>
<td>压缩的 js，后缀名 .js.gz，加 Content-Encoding 声明</td>
<td>√</td>
<td>√</td>
<td>×</td>
</tr>
<tr>
<td>压缩的 js，后缀名 .js，加 Content-Encoding 声明</td>
<td>√</td>
<td>√</td>
<td>√</td>
</tr>
</tbody>
</table>
<p>所以最好的办法是用 gzip 压缩，但不添加 .gz 保持原文件的后缀名，正确添加 Content-Encoding 声明。这样可以保证多数浏览器可以正确识别。但也有个缺点，就是维护起来就比较麻烦了。</p>
<p>-EOF-<br />
<h3>相关文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/howto-config-virtualhost-with-apache-and-tomcat-on-ubuntu.html" title="apache2 和 tomcat5.5 集成及虚拟主机配置">apache2 和 tomcat5.5 集成及虚拟主机配置</a></li>
<li><a href="http://blog.belltoy.net/take_care_of_source_files_encoding.html" title="源代码的字符集不同带来的问题">源代码的字符集不同带来的问题</a></li>
<li><a href="http://blog.belltoy.net/pathinfo-of-thinkphp-effect-on-site-performance.html" title="ThinkPHP 框架的 PATHINFO 模式对站点性能的影响">ThinkPHP 框架的 PATHINFO 模式对站点性能的影响</a></li>
<li><a href="http://blog.belltoy.net/summary-of-2008.html" title="2008年终总结">2008年终总结</a></li>
<li><a href="http://blog.belltoy.net/css-div-is-not-standard-layout.html" title="CSS+DIV不是标准布局">CSS+DIV不是标准布局</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/notes-of-gzip-compression.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>《程序员修炼之道》书评</title>
		<link>http://blog.belltoy.net/reveiw-the-pragmatic-programmer.html</link>
		<comments>http://blog.belltoy.net/reveiw-the-pragmatic-programmer.html#comments</comments>
		<pubDate>Wed, 12 Aug 2009 14:36:49 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Other]]></category>

		<category><![CDATA[book]]></category>

		<category><![CDATA[programmer]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=249</guid>
		<description><![CDATA[
在大学的时候，编程是我的兴趣，也是当时给自己定位的职业方向。
当我在图书馆里看到这本《程序员修炼之道》的时候，直觉告诉我觉得应该看看这本书，或许对我的成长有帮助。读完之后我更加肯定了自己的直觉是对的。当时的我虽然没有实际项目的开发经验，不是一时半会就能领悟其意，但我明白，这本书中总结的原则和方法对我来说是极为宝贵的，于是买了一本放在床头。
参加工作后，随着编程经验的积累，我越来越能体会这本书中观点。每一次重读书中的章节，都会有新的收获；结合自己的每次经历，都能与之共鸣。——这是对我影响最深的一本书，也是我向朋友和同事推荐次数最多的一本书。有趣的是，书前 Kevin Ruland 的评论说到：这是我唯一不会出借的一本书。究竟是一本什么样的书会让大师都如此爱不释手？

这本书所涉及的内容很广，涵盖了程序员成长过程中和软件开发过程中需要注意的地方。从程序员的个体哲学到编码过程中的各个环节，再到团队的项目管理；从程序员要如何扩充知识，如何思考问题，如何利用有效的工具打造个人的工作环境，到项目启动之前如何建立一些基本准则，如何分析、设计、编写、测试、重构，如何实现自动化，甚至是项目团队中提高实效的原则。书中的内容全部都是来自经验的总结，倡导编程中正确的观念和良好的习惯，而这正是优秀的程序员必须拥有的良好素质。
书中讲述的原则源于实践，高于实践，它们蕴涵着前辈们的智慧。随着知识的扩展、编程体验的增加，对这本书中的内容的理解也会愈加深刻。反过来，对前辈菁华的吸收，有助于我们提高编程水平，开发出更好的产品。
我深信这不是一本只要读一遍的书。这些原则看似简单，但细细品味一番，却是大哲大道，环环相扣，要理解透彻并不容易。例如，提示44告诉我们“不要靠巧合编程”，这道理看起来好像很简单，但我发现实际工作中还是很容易就犯这个错。细想一下BUG列表中的问题，其中的大多数不正是由于作了不正确的假设，或者是想当然造成的吗？要是一开始就有深思熟虑，经过了合理的设计，完整有效地进行测试，大部分都可以避免罢！而思考、设计、测试又紧扣书中其它章节。
曾经和朋友讨论关于员工培训的事。如果给程序员做培训的话，我首选的材料就是这本《程序员修炼之道》。
这是应周筠老师的邀请，为这本书的再版写的书评。第一次写这样的文章，写得不好，但这确实是我的感受。
-EOF-
相关文章

新的封面
评论《程序员修炼之道:从小工到专家》

]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.douban.com/subject/1516799/" class="imglink"><img style="float:left;padding:0 20px 20px 0;border:0" src="http://otho.douban.com/mpic/s1886484.jpg" alt="《程序员修炼之道》" /></a><br />
在大学的时候，编程是我的兴趣，也是当时给自己定位的职业方向。<br />
当我在图书馆里看到这本《程序员修炼之道》的时候，直觉告诉我觉得应该看看这本书，或许对我的成长有帮助。读完之后我更加肯定了自己的直觉是对的。当时的我虽然没有实际项目的开发经验，不是一时半会就能领悟其意，但我明白，这本书中总结的原则和方法对我来说是极为宝贵的，于是买了一本放在床头。</p>
<p>参加工作后，随着编程经验的积累，我越来越能体会这本书中观点。每一次重读书中的章节，都会有新的收获；结合自己的每次经历，都能与之共鸣。——这是对我影响最深的一本书，也是我向朋友和同事推荐次数最多的一本书。有趣的是，书前 Kevin Ruland 的评论说到：这是我唯一不会出借的一本书。究竟是一本什么样的书会让大师都如此爱不释手？</p>
<p><span id="more-249"></span></p>
<p>这本书所涉及的内容很广，涵盖了程序员成长过程中和软件开发过程中需要注意的地方。从程序员的个体哲学到编码过程中的各个环节，再到团队的项目管理；从程序员要如何扩充知识，如何思考问题，如何利用有效的工具打造个人的工作环境，到项目启动之前如何建立一些基本准则，如何分析、设计、编写、测试、重构，如何实现自动化，甚至是项目团队中提高实效的原则。书中的内容全部都是来自经验的总结，倡导编程中正确的观念和良好的习惯，而这正是优秀的程序员必须拥有的良好素质。</p>
<p>书中讲述的原则源于实践，高于实践，它们蕴涵着前辈们的智慧。随着知识的扩展、编程体验的增加，对这本书中的内容的理解也会愈加深刻。反过来，对前辈菁华的吸收，有助于我们提高编程水平，开发出更好的产品。</p>
<p>我深信这不是一本只要读一遍的书。这些原则看似简单，但细细品味一番，却是大哲大道，环环相扣，要理解透彻并不容易。例如，提示44告诉我们“不要靠巧合编程”，这道理看起来好像很简单，但我发现实际工作中还是很容易就犯这个错。细想一下BUG列表中的问题，其中的大多数不正是由于作了不正确的假设，或者是想当然造成的吗？要是一开始就有深思熟虑，经过了合理的设计，完整有效地进行测试，大部分都可以避免罢！而思考、设计、测试又紧扣书中其它章节。</p>
<p>曾经和朋友讨论关于员工培训的事。如果给程序员做培训的话，我首选的材料就是这本《程序员修炼之道》。</p>
<hr />这是应<a href="http://yeka.blogbus.com" target="_blank">周筠老师</a>的邀请，为这本书的再版写的书评。第一次写这样的文章，写得不好，但这确实是我的感受。</p>
<p>-EOF-<br />
<h3>相关文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/new-cover.html" title="新的封面">新的封面</a></li>
<li><a href="http://blog.belltoy.net/read-the-pragmatic-programmer.html" title="评论《程序员修炼之道:从小工到专家》">评论《程序员修炼之道:从小工到专家》</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/reveiw-the-pragmatic-programmer.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>修个手机都这么难</title>
		<link>http://blog.belltoy.net/bad-service-industries-in-china.html</link>
		<comments>http://blog.belltoy.net/bad-service-industries-in-china.html#comments</comments>
		<pubDate>Sat, 08 Aug 2009 13:30:03 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=246</guid>
		<description><![CDATA[Moto E6 手机的耳机插孔里的弹片没有复位，导致没插耳机也一直在耳机模式下。所有修手机的都说是主板或者芯片坏了，收费100到500，甚至有人在没有检测的情况下就妄下结论。还有人扬言如果是弹片没有复位他没办法修，如果我承认是主板或者芯片坏了他就可以修。这他妈的不是抢钱吗？！假如你咳嗽，我说你要换个肺，不然我没办法治，你干不干？
上海Moto维修中心跟客户交流的是前台小姐，技术人员不知道躲在哪里。非专业用户可能被骗说是主板问题，专业用户的意见没法传达到技术维修人员那里，这样怎么修手机？检测完前台小姐出来答话，说是主板问题，修要480，我问主板什么问题，她才说是主板上的芯片问题，再问什么芯片，答不上来。
什么芯片坏了要480？为什么不说出来？怕被我知道后他们的谎言就穿帮了？什么芯片这么好要480？这么好的芯片要是坏了我的手机除了一直在耳机模式之外就什么问题都没有了？

满街的修手机都这样，大品牌客服也这样，就没人管？Moto的维修协议上还说要是手机被他们修坏了他们不负责。很多所谓的专业技术维修人员连基础的电子和数字电路的原理都没我清楚。公职人员拿了纳税人的钱都在干嘛？是不是管小摊没好处拿，管大企业怕影响税收？作为弱势群体很无助啊！我要自己修！
当然换主板在大部分情况下都能修复手机的问题，但有必要吗？我更倾向于把问题最小化定位，尽量针对最小的模块修复。就像鼠标左键单击变双击一样，没必要换整个鼠标，只要把按键那个元件换一个焊上去就好了。
这个问题让我想起这篇文章《当国联航弄坏了我的吉他》。
关于 Moto E6 手机的这个问题参见：

百度知道
ZOL中关村在线

-EOF-
随机文章

Java5/6中的字体自定义设置与美化
闭包的用处
《程序员修炼之道》书评
源代码的字符集不同带来的问题
全国哀悼日

]]></description>
			<content:encoded><![CDATA[<p>Moto E6 手机的耳机插孔里的弹片没有复位，导致没插耳机也一直在耳机模式下。所有修手机的都说是主板或者芯片坏了，收费100到500，甚至有人在没有检测的情况下就妄下结论。还有人扬言如果是弹片没有复位他没办法修，如果我承认是主板或者芯片坏了他就可以修。这他妈的不是抢钱吗？！假如你咳嗽，我说你要换个肺，不然我没办法治，你干不干？</p>
<p>上海Moto维修中心跟客户交流的是前台小姐，技术人员不知道躲在哪里。非专业用户可能被骗说是主板问题，专业用户的意见没法传达到技术维修人员那里，这样怎么修手机？检测完前台小姐出来答话，说是主板问题，修要480，我问主板什么问题，她才说是主板上的芯片问题，再问什么芯片，答不上来。</p>
<p>什么芯片坏了要480？为什么不说出来？怕被我知道后他们的谎言就穿帮了？什么芯片这么好要480？这么好的芯片要是坏了我的手机除了一直在耳机模式之外就什么问题都没有了？</p>
<p><span id="more-246"></span></p>
<p>满街的修手机都这样，大品牌客服也这样，就没人管？Moto的维修协议上还说要是手机被他们修坏了他们不负责。很多所谓的专业技术维修人员连基础的电子和数字电路的原理都没我清楚。公职人员拿了纳税人的钱都在干嘛？是不是管小摊没好处拿，管大企业怕影响税收？作为弱势群体很无助啊！我要自己修！</p>
<p>当然换主板在大部分情况下都能修复手机的问题，但有必要吗？我更倾向于把问题最小化定位，尽量针对最小的模块修复。就像鼠标左键单击变双击一样，没必要换整个鼠标，只要把按键那个元件换一个焊上去就好了。</p>
<p>这个问题让我想起这篇文章<a href="http://blog.sina.com.cn/s/blog_53742bef0100f2wi.html">《当国联航弄坏了我的吉他》</a>。</p>
<p>关于 Moto E6 手机的这个问题参见：</p>
<ol>
<li><a href="http://zhidao.baidu.com/question/54835124.html">百度知道</a></li>
<li><a href="http://moto.zol.com.cn/frmView.php?frameon=yes&amp;subcatid=295&amp;bookid=1559445&amp;ref0=http://www.google.com/search?hl=en&amp;client=firefox-a&amp;rls=com.ubuntu%3Azh-CN%3Aunofficial&amp;hs=OcS&amp;q=e6+%E6%B2%A1%E5%A3%B0%E9%9F%B3&amp;aq=f&amp;oq=&amp;aqi=g10">ZOL中关村在线</a></li>
</ol>
<p>-EOF-<br />
<h3>随机文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/generate-image-from-remote-ftpserver-with-jsp.html" title="JSP连接远程FTP服务器，生成缩略图">JSP连接远程FTP服务器，生成缩略图</a></li>
<li><a href="http://blog.belltoy.net/oracle-sql-optimize.html" title="Oracle 查询优化">Oracle 查询优化</a></li>
<li><a href="http://blog.belltoy.net/national-mourning.html" title="全国哀悼日">全国哀悼日</a></li>
<li><a href="http://blog.belltoy.net/send-mail-with-perl.html" title="perl发邮件脚本">perl发邮件脚本</a></li>
<li><a href="http://blog.belltoy.net/new-cover.html" title="新的封面">新的封面</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/bad-service-industries-in-china.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>闭包的用处</title>
		<link>http://blog.belltoy.net/useage-of-javascript-closure.html</link>
		<comments>http://blog.belltoy.net/useage-of-javascript-closure.html#comments</comments>
		<pubDate>Fri, 07 Aug 2009 11:37:22 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=242</guid>
		<description><![CDATA[闭包的原理懂了，但闭包在 JavaScript 的实际编程中有什么用呢？这是一个同事的提问。闭包可以用在很多地方，但我还不能完全总结出来，最常用的使用方式有以下几种。

延迟调用
setTimeout 函数允许在指定时间之后在全局对象（window 对象）里执行一个无参数函数。利用闭包的特性，我们就可以给这个函数传递参数。

1
2
3
4
5
6
7
function dosomething&#40;param&#41; &#123;
    return &#40;function&#40;&#41; &#123;
        //这里可以得到 param 这个参数
        alert&#40;param&#41;;
    &#125;&#41;;
&#125;
setTimeout&#40;dosomething&#40;'参数'&#41;, 1000&#41;;

命名空间
闭包包含了函数代码和绑定了自由变量的计算环境，这个环境就可以给函数提供一个私有的命名空间。这个特性可以用在很多情况下。例如一个字符串解析函数需要一个特殊字符列表，如果把这个列表定义在函数体中，那么每次调用这个函数的时候都要重新初始化一次特殊字符列表。有两种方法可以避免这种重复计算，一是把特殊字符列表定义成全局的变量。但这样至少会产生两个问题，污染了全局命名空间，同时这个全局变量在任何地方都可以被修改。第二种方法就是利用闭包，示例代码如下。

1
2
3
4
5
6
7
8
var parse = function&#40;&#41;&#123;
    var list = &#91;'t', 'n', '\' /* other */];
    return [...]]]></description>
			<content:encoded><![CDATA[<p>闭包的原理懂了，但闭包在 JavaScript 的实际编程中有什么用呢？这是一个同事的提问。闭包可以用在很多地方，但我还不能完全总结出来，最常用的使用方式有以下几种。</p>
<p><span id="more-242"></span></p>
<h3>延迟调用</h3>
<p>setTimeout 函数允许在指定时间之后在全局对象（window 对象）里执行一个无参数函数。利用闭包的特性，我们就可以给这个函数传递参数。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> dosomething<span style="color: #009900;">&#40;</span>param<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">//这里可以得到 param 这个参数</span>
        <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>param<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
setTimeout<span style="color: #009900;">&#40;</span>dosomething<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'参数'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>命名空间</h3>
<p>闭包包含了函数代码和绑定了自由变量的计算环境，这个环境就可以给函数提供一个私有的命名空间。这个特性可以用在很多情况下。例如一个字符串解析函数需要一个特殊字符列表，如果把这个列表定义在函数体中，那么每次调用这个函数的时候都要重新初始化一次特殊字符列表。有两种方法可以避免这种重复计算，一是把特殊字符列表定义成全局的变量。但这样至少会产生两个问题，污染了全局命名空间，同时这个全局变量在任何地方都可以被修改。第二种方法就是利用闭包，示例代码如下。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> parse <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> list <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'t'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'n'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\'</span> /* other */];
    return function(str /* 要解析的目标字符串 */) {
        //do parse
    };
}();
&nbsp;
parse('</span>hello<span style="color: #3366CC;">');</span></pre></td></tr></table></div>

<p>这样，不管调用多少次 parse 函数，特殊字符列表都不会重新初始化了，而且外部任何地方都无法访问这个列表。</p>
<p>通过闭包可以做什么，以上只是举两个比较常见的例子，有<a href="http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html" title="理解 JavaScript 闭包">一篇文章</a>说闭包什么都可以做。有的时候不用闭包可能也可以实现相应的功能，但闭包使 JavaScript 变得更加灵活，可以让你写出更加优雅的代码。要详细解答这个问题要通过大量的实践和总结了，我们只要对它的原理理解了，平时开发的时候多思考，就知道该不该用闭包了。</p>
<p>-EOF-<br />
<h3>相关文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/learning-from-summarize.html" title="从总结中学习">从总结中学习</a></li>
<li><a href="http://blog.belltoy.net/javascript_scope_call_object_closure.html" title="Javascript 的词法作用域、调用对象和闭包">Javascript 的词法作用域、调用对象和闭包</a></li>
<li><a href="http://blog.belltoy.net/improve-ajax-in-jquery.html" title="jQuery中ajax方法的改进">jQuery中ajax方法的改进</a></li>
<li><a href="http://blog.belltoy.net/summary-of-2008.html" title="2008年终总结">2008年终总结</a></li>
<li><a href="http://blog.belltoy.net/have-a-try.html" title="牛刀小试">牛刀小试</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/useage-of-javascript-closure.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>从总结中学习</title>
		<link>http://blog.belltoy.net/learning-from-summarize.html</link>
		<comments>http://blog.belltoy.net/learning-from-summarize.html#comments</comments>
		<pubDate>Thu, 06 Aug 2009 19:04:35 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Web]]></category>

		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=239</guid>
		<description><![CDATA[
这本书的书名叫 JavaScript: The Good Parts，内容共 150 页左右。原本以为这么薄的书直接在书店看完就好。但当我在书店花了大约半小时时间快速看了一遍之后我觉得它值得我买下来。
它概括了 JavaScript 这个脚本语言的核心内容，不仅总结了语言的精华部分，还指出了“鸡肋”和“糟粕”。如果说犀牛书展现了 JavaScript 特性的丰富和功能的强大，这本书就体现了 JavaScript 语言轻巧简洁的特点。
其实 JavaScript 就是这么简洁，但是它很灵活，使用得好，可以编写出功能强大的程序。语言中核心的内容，也就是犀牛书的第一部分，全部在这本书中被总结出来了。但这并不表示可以从这本书入门，它不是入门级的，不适合初学者。作为概括总结，它是一本很好的帮助你提高 JavaScript 水平的书籍，因为总结也是学习的过程。

这本书的特点是，薄但内容丰富。它用精炼的文字、形象的语法图（railroad diagram）和简短的代码片断总结了 JavaScript 的核心内容。对于对 JavaScript 已经有较深理解的人来说，它可以帮助你整理总结并加深对 JavaScript 的理解，对于了解程度低一点的人来说，它可以帮助你学习 JavaScript 的编程思想。不过就像作者的前言所说的，必须反复阅读。这也正是我决定购买这本书的原因。
书的最后那个 json_parse 的例子给我的印象很深。这是本书唯一一个完整的实例代码，它包含了 JavaScript 中很多重要的知识点和代码设计风格（比如闭包），很值得研究学习。
-EOF-
相关文章

闭包的用处
Javascript 的词法作用域、调用对象和闭包
jQuery中ajax方法的改进
2008年终总结
牛刀小试

]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.douban.com/subject/3590768/" class="imglink"><img style="float:left;padding:0 20px 20px 0;border:0" src="http://t.douban.com/mpic/s3651235.jpg" alt="JavaScript语言精粹" /></a></p>
<p>这本书的书名叫 JavaScript: The Good Parts，内容共 150 页左右。原本以为这么薄的书直接在书店看完就好。但当我在书店花了大约半小时时间快速看了一遍之后我觉得它值得我买下来。</p>
<p>它概括了 JavaScript 这个脚本语言的核心内容，不仅总结了语言的精华部分，还指出了“鸡肋”和“糟粕”。如果说犀牛书展现了 JavaScript 特性的丰富和功能的强大，这本书就体现了 JavaScript 语言轻巧简洁的特点。</p>
<p>其实 JavaScript 就是这么简洁，但是它很灵活，使用得好，可以编写出功能强大的程序。语言中核心的内容，也就是犀牛书的第一部分，全部在这本书中被总结出来了。但这并不表示可以从这本书入门，它不是入门级的，不适合初学者。作为概括总结，它是一本很好的帮助你提高 JavaScript 水平的书籍，因为总结也是学习的过程。</p>
<p><span id="more-239"></span></p>
<p>这本书的特点是，薄但内容丰富。它用精炼的文字、形象的语法图（railroad diagram）和简短的代码片断总结了 JavaScript 的核心内容。对于对 JavaScript 已经有较深理解的人来说，它可以帮助你整理总结并加深对 JavaScript 的理解，对于了解程度低一点的人来说，它可以帮助你学习 JavaScript 的编程思想。不过就像作者的前言所说的，必须反复阅读。这也正是我决定购买这本书的原因。</p>
<p>书的最后那个 json_parse 的例子给我的印象很深。这是本书唯一一个完整的实例代码，它包含了 JavaScript 中很多重要的知识点和代码设计风格（比如闭包），很值得研究学习。</p>
<p>-EOF-<br />
<h3>相关文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/useage-of-javascript-closure.html" title="闭包的用处">闭包的用处</a></li>
<li><a href="http://blog.belltoy.net/javascript_scope_call_object_closure.html" title="Javascript 的词法作用域、调用对象和闭包">Javascript 的词法作用域、调用对象和闭包</a></li>
<li><a href="http://blog.belltoy.net/improve-ajax-in-jquery.html" title="jQuery中ajax方法的改进">jQuery中ajax方法的改进</a></li>
<li><a href="http://blog.belltoy.net/summary-of-2008.html" title="2008年终总结">2008年终总结</a></li>
<li><a href="http://blog.belltoy.net/have-a-try.html" title="牛刀小试">牛刀小试</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/learning-from-summarize.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Javascript 的词法作用域、调用对象和闭包</title>
		<link>http://blog.belltoy.net/javascript_scope_call_object_closure.html</link>
		<comments>http://blog.belltoy.net/javascript_scope_call_object_closure.html#comments</comments>
		<pubDate>Tue, 28 Jul 2009 03:20:54 +0000</pubDate>
		<dc:creator>belltoy</dc:creator>
		
		<category><![CDATA[Database]]></category>

		<category><![CDATA[Web]]></category>

		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.belltoy.net/?p=211</guid>
		<description><![CDATA[昨天又有人问我 Javascript 闭包到底是什么，我发现三言两语无法解释清楚，干脆就写出来吧。其实关于 Javascript 的函数作用域、调用对象和闭包之间的关系很微妙，关于它们的文章已经有很多，但不知道为什么很多新手都难以理解。我就尝试用比较通俗的语言来表达我自己的理解吧。

作用域 Scope
Javascript 中的函数属于词法作用域，也就是说函数在它被定义时的作用域中运行而不是在被执行时的作用域内运行。这是犀牛书上的说法。但“定义时”和“执行（被调用）时”这两个东西有些人搞不清楚。简单来说，一个函数A在“定义时”就是 function A(){} 这个语句执行的时候就是定义这个函数的时候，而A被调用的时候是 A() 这个语句执行的时候。这两个概念一定要分清楚。
那词法作用域（以下称之为“作用域”，除非特别指明）到底是什么呢？它是个抽象的概念，说白了它就是一个“范围”，scope 在英文里就是范围的意思。一个函数的作用域是它被定义时它所处的“范围”，也就是它外层的“范围”，这个“范围”包含了外层的变量属性，这个“范围”被设置成这个函数的一个内部状态。一个全局函数被定义的时候，全局（这个函数的外层）的“范围”就被设置成这个全局函数的一个内部状态。一个嵌套函数被定义的时候，被嵌套函数（外层函数）的“范围”就被设置成这个嵌套函数的一个内部状态。这个“内部状态”实际上可以理解成作用域链，见下文。
当一个函数被调用时，在这个函数里，它能访问到它的这个内部状态，也就可以访问整个作用域链上的所有变量，当然也就包括了外部变量。（实际上是从“调用对象链”里访问到的。好像有问题吧，请接着阅读。）
照以上说法，一个函数的作用域是它被定义的时候所处的“范围”，那么 Javascript 里的函数作用域是在函数被定义的时候就确定了，所以它是静态的作用域，词法作用域又称为静态作用域。
调用对象 Call Object
一个函数的调用对象是动态的，它是在这个函数被调用时才被实例化的。我们已经知道，当一个函数被定义的时候，已经确定了它的作用域链。当 Javascript 解释器调用一个函数的时候，它会添加一个新的对象（调用对象）到这个作用域链的前面。这个调用对象的一个属性被初始化成一个名叫 arguments 的属性，它引用了这个函数的 Arguments 对象，Arguments 对象是函数的实际参数。所有用 var 语句声明的本地变量也被定义在这个调用对象里。这个时候，调用对象处在作用域链的头部，本地变量、函数形式参数和 Arguments 对象全部都在这个函数的范围里了。当然，这个时候本地变量、函数形式参数和 Arguments 对象就覆盖了作用域链里同名的属性。
作用域、作用域链和调用对象之间的关系
我的理解是，作用域是是抽象的，而调用对象是实例化的。
在函数被定义的时候，实际上也是它外层函数执行的时候，它确定的作用域链实际上是它外层函数的调用对象链；当函数被调用时，它的作用域链是根据定义的时候确定的作用域链（它外层函数的调用对象链）加上一个实例化的调用对象。所以函数的作用域链实际上是调用对象链。在一个函数被调用的时候，它的作用域链（或者称调用对象链）实际上是它在被定义的时候确定的作用域链的一个超集。
它们之间的关系可以表示成：作用域⊃作用域链⊇调用对象。
太绕口了，举例说明吧：

1
2
3
4
5
6
function f&#40;x&#41; &#123;
    var g = function &#40;&#41; &#123; return x; &#125;
    return g;
&#125;
var g1 = f&#40;1&#41;;
alert&#40;g1&#40;&#41;&#41;;  //输出 1

假设我们把全局看成类似以下这样的一个大匿名函数：

1
2
3
&#40;function&#40;&#41; &#123;
 [...]]]></description>
			<content:encoded><![CDATA[<p>昨天又有人问我 Javascript 闭包到底是什么，我发现三言两语无法解释清楚，干脆就写出来吧。其实关于 Javascript 的函数作用域、调用对象和闭包之间的关系很微妙，关于它们的文章已经有很多，但不知道为什么很多新手都难以理解。我就尝试用比较通俗的语言来表达我自己的理解吧。</p>
<p><span id="more-211"></span></p>
<h4>作用域 Scope</h4>
<p>Javascript 中的函数属于词法作用域，也就是说函数在它被定义时的作用域中运行而不是在被执行时的作用域内运行。这是犀牛书上的说法。但“定义时”和“执行（被调用）时”这两个东西有些人搞不清楚。简单来说，一个函数A在“定义时”就是 function A(){} 这个语句执行的时候就是定义这个函数的时候，而A被调用的时候是 A() 这个语句执行的时候。这两个概念一定要分清楚。</p>
<p>那词法作用域（以下称之为“作用域”，除非特别指明）到底是什么呢？它是个抽象的概念，说白了它就是一个“范围”，scope 在英文里就是范围的意思。一个函数的作用域是它被定义时它所处的“范围”，也就是它外层的“范围”，这个“范围”包含了外层的变量属性，这个“范围”被设置成这个函数的一个内部状态。一个全局函数被定义的时候，全局（这个函数的外层）的“范围”就被设置成这个全局函数的一个内部状态。一个嵌套函数被定义的时候，被嵌套函数（外层函数）的“范围”就被设置成这个嵌套函数的一个内部状态。这个“内部状态”实际上可以理解成作用域链，见下文。</p>
<p>当一个函数被调用时，在这个函数里，它能访问到它的这个内部状态，也就可以访问整个作用域链上的所有变量，当然也就包括了外部变量。（实际上是从“调用对象链”里访问到的。好像有问题吧，请接着阅读。）</p>
<p>照以上说法，一个函数的作用域是它被定义的时候所处的“范围”，那么 Javascript 里的函数作用域是在函数被定义的时候就确定了，所以它是静态的作用域，词法作用域又称为静态作用域。</p>
<h4>调用对象 Call Object</h4>
<p>一个函数的调用对象是动态的，它是在这个函数被调用时才被实例化的。我们已经知道，当一个函数被定义的时候，已经确定了它的作用域链。当 Javascript 解释器调用一个函数的时候，它会添加一个新的对象（调用对象）到这个作用域链的前面。这个调用对象的一个属性被初始化成一个名叫 arguments 的属性，它引用了这个函数的 Arguments 对象，Arguments 对象是函数的实际参数。所有用 var 语句声明的本地变量也被定义在这个调用对象里。这个时候，调用对象处在作用域链的头部，本地变量、函数形式参数和 Arguments 对象全部都在这个函数的范围里了。当然，这个时候本地变量、函数形式参数和 Arguments 对象就覆盖了作用域链里同名的属性。</p>
<h4>作用域、作用域链和调用对象之间的关系</h4>
<p>我的理解是，作用域是是抽象的，而调用对象是实例化的。</p>
<p>在函数被定义的时候，实际上也是它外层函数执行的时候，它确定的作用域链实际上是它外层函数的调用对象链；当函数被调用时，它的作用域链是根据定义的时候确定的作用域链（它外层函数的调用对象链）加上一个实例化的调用对象。所以函数的作用域链实际上是调用对象链。在一个函数被调用的时候，它的作用域链（或者称调用对象链）实际上是它在被定义的时候确定的作用域链的一个超集。</p>
<p>它们之间的关系可以表示成：<strong>作用域⊃作用域链⊇调用对象</strong>。</p>
<p>太绕口了，举例说明吧：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> g <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> g<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> g1 <span style="color: #339933;">=</span> f<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>g1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">//输出 1</span></pre></td></tr></table></div>

<p>假设我们把全局看成类似以下这样的一个大匿名函数：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">//这里是全局范围</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>那么例子就可以看成是：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> g <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> x<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> g<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #003366; font-weight: bold;">var</span> g1 <span style="color: #339933;">=</span> f<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>g1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">//输出 1</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<ol start="0">
<li>全局的大匿名函数被定义的时候，它没有外层，所以它的作用域链是空的。</li>
<li>全局的大匿名函数直接被执行，全局的作用域链里只有一个 '<strong>全局调用对象</strong>'。</li>
<li>函数 f 被定义，此时函数 f 的作用域链是它外层的作用域链，即 '<strong>全局调用对象</strong>'。</li>
<li>函数 f(1) 被执行，它的作用域链是新的 f(1) 调用对象加上函数 f 被定义的时候的作用域链，即 '<strong>f(1) 调用对象-&gt;全局调用对象</strong>'。</li>
<li>函数 g （它要被返回给 g1，就命名为 g1吧）在 f(1) 中被定义，它的作用域链是它外层的函数 f(1) 的作用域链，即 '<strong>f(1) 调用对象-&gt;全局调用对象</strong>'。</li>
<li>函数 f(1) 返回函数 g 的定义给 g1。</li>
<li>函数 g1 被执行，它的作用域链是新的 g(1) 调用对象加上外层 f(1) 的作用域链，即 '<strong>g1 调用对象-&gt;f(1)调用对象-&gt;全局调用对象</strong>'。</li>
</ol>
<p>这样看就很清楚了吧。</p>
<h4>闭包 Closuer</h4>
<p>闭包的一个简单的说法是，当嵌套函数在被嵌套函数之外调用的时候，就形成了闭包。</p>
<p>之前的那个例子其实就是一个闭包。g1 是在 f(1) 内部定义的，却在 f(1) 返回后才被执行。可以看出，闭包的一个效果就是被嵌套函数 f 返回后，它内部的资源不会被释放。在外部调用 g 函数时，g 可以访问 f 的内部变量。根据这个特性，可以写出很多优雅的代码。</p>
<p>例如要在一个页面上作一个统一的计数器，如果用闭包的写法，可以这么写：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> counter  <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> fns <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;get&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">return</span> i<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
               <span style="color: #3366CC;">&quot;inc&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">++</span>i<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> fns<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">//do something</span>
counter.<span style="color: #660066;">inc</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">//do something else</span>
counter.<span style="color: #660066;">inc</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> c_value <span style="color: #339933;">=</span> counter.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">//now c_value is 2</span></pre></td></tr></table></div>

<p>这样，在内存中就维持了一个变量 i，整个程序中的其它地方都无法直接操作 i 的值，只能通过 counter 的两个操作。</p>
<p>在 setTimeout(fn, delay) 的时候，我们不能给 fn 这个函数句柄传参数，但可以通过闭包的方法把需要的参数绑定到 fn 内部。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>delay<span style="color: #339933;">=</span><span style="color: #CC0000;">1000</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++,</span> delay <span style="color: #339933;">+=</span><span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'i:'</span> <span style="color: #339933;">+</span> i <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot; delay:&quot;</span> <span style="color: #339933;">+</span> delay<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> delay<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>这样，打印出来的值都是</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">i<span style="color: #339933;">:</span><span style="color: #CC0000;">5</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">6000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">5</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">6000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">5</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">6000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">5</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">6000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">5</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">6000</span></pre></div></div>

<p>改用闭包的方式可以很容易绑定要传进去的参数：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> delay<span style="color: #339933;">=</span><span style="color: #CC0000;">1000</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #CC0000;">5</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++,</span> delay <span style="color: #339933;">+=</span> <span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> _delay<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
        setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
            console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'i:'</span><span style="color: #339933;">+</span>a<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot; delay:&quot;</span><span style="color: #339933;">+</span>_delay<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> _delay<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> delay<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>输出：</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">i<span style="color: #339933;">:</span><span style="color: #CC0000;">0</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">1000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">2000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">2</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">3000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">3</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">4000</span>
i<span style="color: #339933;">:</span><span style="color: #CC0000;">4</span> delay<span style="color: #339933;">:</span><span style="color: #CC0000;">5000</span></pre></div></div>

<p>闭包还有一个很常用的地方，就是在绑定事件的回调函数的时候。也是同样的道理，绑定的函数句柄不能做参数，但可以通过闭包的形式把参数绑定进去。</p>
<h4>总结</h4>
<ol>
<li>函数的词法作用域和作用域链是不同的东西，词法作用域是抽象概念，作用域链是实例化的调用对象链。</li>
<li>函数在被定义的时候，同时也是它外层的函数在被执行的时候。</li>
<li>函数在被定义的时候它的词法作用域就已经确定了，但它仍然是抽象的概念，没有也不能被实例化。</li>
<li> 函数在被定义的时候还确定了一个东西，就是它外层函数的作用域链，这个是实例化的东西。</li>
<li>函数在被多次调用的时候，它的作用域链都是不同的。</li>
<li>闭包很强大。犀牛书说得对，理解了这些东西，你就可以自称是高级 Javascript 程序员了。因为利用好这些概念，可以玩转 Javascript 的很多设计模式。</li>
</ol>
<p>-EOF-<br />
<h3>相关文章</h3>
<ul class="related_post">
<li><a href="http://blog.belltoy.net/useage-of-javascript-closure.html" title="闭包的用处">闭包的用处</a></li>
<li><a href="http://blog.belltoy.net/learning-from-summarize.html" title="从总结中学习">从总结中学习</a></li>
<li><a href="http://blog.belltoy.net/improve-ajax-in-jquery.html" title="jQuery中ajax方法的改进">jQuery中ajax方法的改进</a></li>
<li><a href="http://blog.belltoy.net/summary-of-2008.html" title="2008年终总结">2008年终总结</a></li>
<li><a href="http://blog.belltoy.net/have-a-try.html" title="牛刀小试">牛刀小试</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.belltoy.net/javascript_scope_call_object_closure.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
