<?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>随网之舞Javascript &amp; DOM &amp; AJAX</title>
	<atom:link href="http://dancewithnet.com/category/design/javascript-dom-ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://dancewithnet.com</link>
	<description>WEB Design{HTML:CSS:Javascript:DOM:AJAX:PHP:Usability}/Viewpoint/Photo/Food/Mood</description>
	<lastBuildDate>Mon, 18 Jul 2011 02:45:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>正则表达式字面量在ECMAScript5中的变化</title>
		<link>http://dancewithnet.com/2011/05/11/what-is-new-about-regular-expression-literals-at-es5/</link>
		<comments>http://dancewithnet.com/2011/05/11/what-is-new-about-regular-expression-literals-at-es5/#comments</comments>
		<pubDate>Wed, 11 May 2011 15:48:59 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1534</guid>
		<description><![CDATA[在《JavaScript语言精粹》的第72页有这样一段：
用正则表达式字面量创建的RegExp对象来共享同一个单实例：
function make_a_matcher(  ) {
    return /a/gi;
}

var x = make_a_matcher(  );
var y = make_a_matcher(  );

// 注... ]]></description>
			<content:encoded><![CDATA[<p>在<a href="http://book.douban.com/subject/3590768/">《JavaScript语言精粹》</a>的第72页有这样一段：</p>
<pre><code>用正则表达式字面量创建的RegExp对象来共享同一个单实例：
function make_a_matcher(  ) {
    return /a/gi;
}

var x = make_a_matcher(  );
var y = make_a_matcher(  );

// 注意：x 和 y 是同一个对象！

x.lastIndex = 10;

document.writeln(y.lastIndex);    // 10</code></pre>
<p>当你<a href="http://dancewithnet.com/lab/2011/regexp-literals/">在浏览器中运行这段代码</a>时，你会发现IE6-IE9、FireFox4、Chrome10、Safari5输出都是0，Firefox 3.6.16输出是10，原因可以在<a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf">ECMAScript5规范</a>第24页和第247页找到：</p>
<p><span id="more-1534"></span></p>
<blockquote><p>
A regular expression literal is an input element that is converted to a RegExp object (see 15.10) each time the literal is evaluated. Two regular expression literals in a program evaluate to regular expression objects that never compare as === to each other even if the two literals&#8217; contents are identical. A RegExp object may also be created at runtime by new RegExp (see 15.10.4) or calling the RegExp constructor as a function (15.10.3).</p>
<p>7.8.5: Regular expression literals now return a unique object each time the literal is evaluated. This change is detectable by any programs that test the object identity of such literal values or that are sensitive to the shared side effects.</p></blockquote>
<p>也就是说在ECMAScript3规范中，用正则表达式创建的RegExp对象会共享同一个实例，而在ECMAScript5中则是两个独立的实例。《JavaScript语言精粹》出版时ECMAScript5还没有发布，在这个问题上书和ECMAScript3标准保持了一致。FireFox3.6遵循了ECMAScript3标准，所以结果与书中一致，而最新的Firefox4、Chrome和Safari5都遵循ECMAScript5标准，至于IE6-IE8都没有很好的遵循ECMAScript3标准，不过在这个问题上反而处理对了。很明显ECMAScript5的规范更符合开发者的期望，那就是相同的正则表达式字面量创建独立的RegExp对象会有不同的lastIndex，才方便分别处理。</p>
<p>在ECMAScript5规范的第247页还有两条来说明ECMAScript5和ECMAScript3在正则表达式字面量上的改变：</p>
<blockquote><p>7.8.5: Edition 5 requires early reporting of any possible RegExp constructor errors that would be produced when converting a RegularExpressionLiteral to a RegExp object. Prior to Edition 5 implementations were permitted to defer the reporting of such errors until the actual execution time creation of the object.<br />
7.8.5: In Edition 5 unescaped “/” characters may appear as a CharacterClass in a regular expression literal. In Edition 3 such a character would have been interpreted as the final character of the literal.</p></blockquote>
<p>第1个是在ECMAScript5中正则表达式字面量转化为RegExp对象时，任何RegExp构造器的错误都会尽早报告，而在之前的规范中是只有对象创建真正执行时才会报错。</p>
<p>第2个是说在ECMAScript5的正则表达式字面量中，未转义的正斜杠“/”可以直接用在正则表达式字符类中。而在ECMAScript3中它只能作为正则表达式字面量的开始和结束字符。<a href="http://dancewithnet.com/lab/2011/regexp-literals/">从IE6-IE9、Firefox3.6-Firefox4.0、Chrome和Safari都可以直接把未转义的正斜杠“/”用在正则表达式字符类中</a>。如：</p>
<pre><code>var my_regexp = /([8/5+4]*).{3}/g;
var str = '8/5+4 is what!';

var result = my_regexp.exec(str); // the same in IE6-9,FF3.6-4.0,Chrome,Safari

for(var i = 0,n = result.length; i < n; ++i){
  document.writeln(result[i]);
}
result[0] = 8/5+4 is
result[1] = 8/5+4
</code></pre>
<p>在《JavaScript语言精粹》第76页也指明在正则表达式的字符类中使用正斜杠“/”需要转义，也是基于ECMAScript3规范。由于正则表达式中需要转义的特殊字符比较多，当心存疑虑时对任何特殊字符都可以使用反斜杠“\”来使其字面化确保安全，不过这个规则不适宜字母和数字。</p>
<p>正则表达式字面量从ECMAScript3到ECMAScript5的改变也蛮符合<a href="http://www.cn-cuckoo.com/2010/10/21/the-design-of-html5-2151.html">HTML5设计原理</a>中提到的2条。一条是“一旦遇到冲突，最终用户优先，其次是作者，其次是实现者，其次标准制定者，最后才是理论上的完满”，另一条是“支持已有内容”。</p>
<p>最后推荐一下<a href="http://xregexp.com/">XRegExp</a>，它是一个非常优秀的正则表达式JavaScript库，兼容多个主流浏览器、ECMAScript3和ECMAScript5。<br />
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2011/05/11/what-is-new-about-regular-expression-literals-at-es5/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>在服务端合并和压缩JavaScript和CSS文件</title>
		<link>http://dancewithnet.com/2010/06/08/minify-js-and-css-files-in-server/</link>
		<comments>http://dancewithnet.com/2010/06/08/minify-js-and-css-files-in-server/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 17:50:57 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Apache &  MySQL &  PHP]]></category>
		<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[Combo Handler]]></category>
		<category><![CDATA[Minify]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1507</guid>
		<description><![CDATA[Web性能优化最佳实践中最重要的一条是减少HTTP请求，它也是YSlow中比重最大的一条规则。减少HTTP请求的方案主要有合并JavaScript和CSS文件、CSS Sprites、图像映射（Image Map）和使用Data URI来编码图... ]]></description>
			<content:encoded><![CDATA[<p>Web性能优化最佳实践中最重要的一条是<a href="http://developer.yahoo.com/performance/rules.html#num_http">减少HTTP请求</a>，它也是<a href="http://developer.yahoo.com/yslow/">YSlow</a>中比重最大的一条规则。减少HTTP请求的方案主要有合并JavaScript和CSS文件、<a href="http://alistapart.com/articles/sprites">CSS Sprites</a>、<a href="http://www.w3.org/TR/html401/struct/objects.html#h-13.6">图像映射（Image Map）</a>和<a href="http://dancewithnet.com/2009/08/15/data-uri-mhtml/">使用Data URI来编码图片</a>。CSS Sprites和图像映射现在已经随处可见了，但由于IE6和IE7不支持Data URI以及性能问题，这项技术尚未大量使用。目前大部分网页中的JavaScript和CSS文件数量和开发时一致，少量的网页会根据实际情况采取本地合并，这些合并中相当多的是有选择地手动完成，每次新的合并都需要重新在本地完成并上传到服务器，比较的随意和繁琐，同样文件的压缩也有类似的情况。而利用服务端的合并和压缩，我们就可以按照开发的逻辑尽可能让文件的颗粒度变小，利用网页中URL的规则来自动实现文件的合并和压缩，这会相当的灵活和高效。</p>
<p><span id="more-1507"></span></p>
<h3>YUI Combo Handler</h3>
<p><a href="http://www.yuiblog.com/blog/2008/07/16/combohandler/">2008年7月YUI Team宣布在YAHOO! CDN上对YUI JavaScript组件提供Combo Handler服务</a>。Combo Handler是Yahoo!开发的一个Apache模块，它实现了开发人员简单方便地通过URL来合并JavaScript和CSS文件，从而大大减少文件请求数。比如在页面上使用<a href="http://developer.yahoo.com/yui/editor/">YUI2的Rich Text Editor组件</a>需要引入多个JavaScript文件，常用方式如下：</p>
<pre><code>&lt;script src="http://yui.yahooapis.com/2.8.0r4/build/yahoo-dom-event/
yahoo-dom-event.js"&gt;&lt;/script&gt;
&lt;script src="http://yui.yahooapis.com/2.8.0r4/build/container/
container_core-min.js"&gt;&lt;/script&gt;
&lt;script src="http://yui.yahooapis.com/2.8.0r4/build/menu/menu-min.js"&gt;&lt;/script&gt;
&lt;script src="http://yui.yahooapis.com/2.8.0r4/build/element/element-min.js"&gt;&lt;/script&gt;
&lt;script src="http://yui.yahooapis.com/2.8.0r4/build/button/button-min.js"&gt;&lt;/script&gt;
&lt;script src="http://yui.yahooapis.com/2.8.0r4/build/editor/editor-min.js"&gt;&lt;/script&gt;
</code></pre>
<p>而使用Combo Handler服务之后，则上述的代码可以写为：</p>
<pre><code>&lt;script src="http://yui.yahooapis.com/combo?
2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.js&#038;
2.8.0r4/build/container/container_core-min.js&#038;
2.8.0r4/build/menu/menu-min.js&#038;
2.8.0r4/build/element/element-min.js&#038;
2.8.0r4/build/button/button-min.js&#038;
2.8.0r4/build/editor/editor-min.js"&gt;&lt;/script&gt;</code></pre>
<p>除了代码的可读性稍稍有一点点降低外，使用Combo Handler服务大大的降低了HTTP请求数，同时也减少了URL代码量，这对于Web性能优化来讲至关重要。所以，随后<a href="http://yuiblog.com/blog/2008/10/17/loading-yui/">YUI从2.6.0开始，其核心组件YUI Loader内置了Combo Handling功能</a>，即使用YUI Loader时，通过配置<code>combine</code>属性就可以把要加载的多个JavaScript或CSS文件按照使用Combo Handler服务的形式合并起来，这时只要静态文件的服务器支持Combo Handler就行了。在YUI中当<code>combine</code>配置为<code>true</code>时，CDN默认是使用Yahoo! CDN（http://yui.yahooapis.com），所以没有任何问题。这正是YUI最迷人的地方之一。</p>
<p>遗憾的是http://yui.yahooapis.com在中国的速度并不佳，本来中国雅虎提供了http://cn.yui.yahooapis.com/ ，但尚未提供Combo Handler服务，同时因种种原因，其更新在<a href="http://cn.yui.yahooapis.com/2.7.0/build/yahoo-event-dom/yahoo-event-dom.js">YUI 2.7.0</a>之后就停滞了。更糟糕的是Yahoo!开发的支持Combo Handler的Apache模块虽然据传有计划开源，但至少现在依旧是私有技术，要使用就需要自己实现类似功能，所以国内类似技术的应用并不太多。</p>
<h3>Minify</h3>
<p>在Google Code上有一个PHP的开源项目叫<a href="http://code.google.com/p/minify/">Minify</a>，它可以合并、精简、Gzip压缩和缓存JavaScript和CSS文件。其文件合并功能就非常类似Combo Handler，只不过URL的语法稍微有点不同。如果Yahoo! CDN安装了Minify，那么上面Rich Text Editor的代码用Minify的默认格式来写就是：</p>
<pre><code>&lt;script src="http://yui.yahooapis.com/min/f=
2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.js,
2.8.0r4/build/container/container_core-min.js,
2.8.0r4/build/menu/menu-min.js,
2.8.0r4/build/element/element-min.js,
2.8.0r4/build/button/button-min.js,
2.8.0r4/build/editor/editor-min.js"&gt;&lt;/script&gt;</code></pre>
<p>本地使用Minify很简单，只需要Apache + PHP环境就OK了：</p>
<ol>
<li>安装好Apache + PHP (<a href="http://dancewithnet.com/2005/09/16/install-apache-and-php-in-windows/">Windows</a>、<a href="http://dancewithnet.com/2010/05/09/run-apache-php-mysql-in-mac-os-x/">Mac</a>)。</li>
<li>下载<a href="http://code.google.com/p/minify/downloads/list">Minify源码</a>，解压，然后把min文件夹复制到指定的根目录下，比如localhost。这时URL的写法大概是<code>http://localhost/min/f=...</code></li>
<li><a href="http://dancewithnet.com/2010/05/29/making-mod-rewrite-and-htaccess-work-on-mac-os-x/">启用Apache的Mod Rewrite模块</a>，然后在min文件夹下<a href="http://www.zendstudio.net/archives/create-htaccess-file-in-windows/">新建.htaccess文件</a>，并添加如下<a href="http://code.google.com/p/minify/source/browse/branches/2.1.4/min/.htaccess">Rewrite规则</a>：
<pre><code>&lt;IfModule mod_rewrite.c&gt;
RewriteEngine on

# You may need RewriteBase on some servers
<span># 如果做了所有的开启Mod Rewrite的设置依旧无效，请城市尝试启用下面这句</span>
#RewriteBase /min

# rewrite URLs like "/min/f=..." to "/min/?f=..."
RewriteRule ^([bfg]=.*)  index.php?$1 [L,NE]
&lt;/IfModule&gt;</code></pre>
<p>如果不启用Mod Rewrite功能，则Minify的URL会类似http://localhost/min/index.php?f=&#8230;，这<a href="http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/">对客户端和中间服务器的缓存不利</a>，而启用了Mod Rewrite之后的URL类似http://localhost/min/f=&#8230;，不仅解决前面问题且更短。</p>
</li>
<li>配置Minify，即编辑min/config.php文件
<pre><code>$min_enableBuilder = true;
<span>//本地使用时可以通过http://dwn/min/builder/来进行配置，外部使用时请设置为false</span>

//$min_cachePath = 'c:\\WINDOWS\\Temp';
//$min_cachePath = '/tmp';
//$min_cachePath = preg_replace('/^\\d+;/', '', session_save_path());
<span>//选择其一，去掉注释设置临时缓存目录，这样可以减少程序运算提高性能</span>

$min_serveOptions['maxAge'] = 1800;
<span>//设置浏览器缓存的时间，为了提升性能建议这个时间设置尽可能的长，比如315360000
//如果需要在不改变URL的情况下更新静态文件，可以采用类似时间戳的方式，
//如http://localhost/min/f=example/example.css&#038;20100601.css
//建议静态文件采用版本号管理，每次修改都需要升级版本号，这样就无需时间戳了，
//如http://localhost/min/f=example/example_1_0_1.css
</span>
$min_serveOptions['minApp']['maxFiles'] = 10;
<span>//参数f获取参数的个数，即合并的文件个数，这个数量完全可以增大，比如50，
//当然可能会遇到URL最大值问题，后会有解释</span>

$min_documentRoot = '';
//$min_documentRoot = substr(__FILE__, 0, strlen(__FILE__) - 15);
//$min_documentRoot = $_SERVER['SUBDOMAIN_DOCUMENT_ROOT'];
<span>//当$min_documentRoot为空时，其值就是$_SERVER['DOCUMENT_ROOT']，
//但合并的文件不在$_SERVER['DOCUMENT_ROOT']下，会导致<a href="http://code.google.com/p/minify/wiki/CommonProblems#Builder_Fails_/_400_Errors">400错误</a>，
//这个时候可以启用第2行或第3行</span>
<span></span>
</code></pre>
</li>
<li>使用Minify
<p>比如，有两个JavaScript文件，<code>http://localhost/example/a.js,http://localhost/example/b.js</code>，那么使用Minify合并的URL是<code>http://localhost/min/f=/example/a.js,/example/b.js</code>，直接把这个URL放到页面中就可以使用了。</p>
</li>
</ol>
<p>实际上Minify不仅仅实现了合并功能，同时默认在合并的同时还会对文件进行精简压缩，如果你在本地本身就对文件进行压缩了，比如使用<a href="http://yuilibrary.com/projects/yuicompressor/">YUI Compressor</a>，那么可以在config.php中进行如下设置取消Minify的压缩以提升性能：</p>
<pre><code>$min_serveOptions['minifiers']['application/x-javascript'] = '';
$min_serveOptions['minifiers']['text/css'] = '';
</code></pre>
<p>如果服务端支持Java，那么也可以<a href="http://code.google.com/p/minify/wiki/CookBook#YUICompressor">对Minify进行简单配置而实现利用YUI Compressor压缩JavaScript和CSS文件</a>。</p>
<p>直接在服务端进行合并和压缩，这非常的灵活，也极大的减轻了前端开发成果的部署过程，真使事半功倍。更多配置请看<a href="http://code.google.com/p/minify/wiki/CookBook">Minify CookBook</a>和<a href="http://code.google.com/p/minify/w/list">Wiki</a></p>
<p>小提示：Minify使用的<a href="http://www.opensource.org/licenses/bsd-license.php">New BSD License</a>，这就意味着使用者可以几乎自由的使用该代码。BSD协议鼓励代码共享，但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码，也允许使用或在BSD代码上开发商业软件发布和销售，因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议，因为可以完全控制这些第三方的代码，在必要的时候可以修改或者二次开发。更多中文信息请看<a href="http://baike.baidu.com/view/1178915.html">《BSD协议》</a>。</p>
<h3>在YUI3中使用Minify</h3>
<p>在YUI2中，合并机制只支持库本身的文件，自定义的文件会单独一一加载。从YUI3开始，模块变得更小，这样就导致使用合并时URL会变长，但<a href="http://support.microsoft.com/kb/208427">在IE下URL的最大值是2083</a>，Apache默认的URL最大值是8192，所以当URL在对应浏览器下超出最大值时，YUI3会自动根据浏览器判断进行拆分成多个合并的URL，并且还提供了<a href="http://developer.yahoo.com/yui/3/api/Loader.html#property_maxURLLength"><code>maxURLLength</code></a>来设置最大值。而从YUI3.1.0开始，不仅仅支持自定义文件的合并，还支持可以使用多个提供合并服务的CDN，即可以对YUI组件使用http://yui.yahooapis.com这个CDN，其余文件使用其他支持合并的CDN，这样非常的实用、方便和灵活。示例<a href="http://dancewithnet.com/lab/2010/yui3-loader-and-minify/">在YUI3中使用Minify</a>就说明了这点。</p>
<p>由于YUI默认URL的合并形式和Minify的不相同，所以在YUI实例化时需要利用正则替换来实现YUI3支持Minify的URL合并形式，但这种方式既不灵活，且有风险，不友好又效率低。比较简单的方式是直接修改YUI 3的源码，如示例<a href="http://dancewithnet.com/lab/2010/yui3-loader-and-minify/fixed.html">在修改后的YUI3中使用Minify</a>。同时，YUI 3.1.*的版本有一个bug，即同时合并JavaScript和CSS时，较短的那个URL结尾处多一个&#038;符号，如<a href="http://dancewithnet.com/lab/2010/yui3-loader-and-minify/">示例在YUI3中使用Minify</a>中：</p>
<pre><code>http://yui.yahooapis.com/combo?3.1.1/build/widget/assets/skins/sam/widget.css&#038;
3.1.1/build/console/assets/skins/sam/console.css&#038;

http://dancewithnet.com/min/b=yui&#038;f=3.1.1/tabview/assets/skins/sam/tabview.css&#038;</code></pre>
<p>这两种都可以使用，虽然<a href="http://dancewithnet.com/2009/11/05/a-little-practice-about-js-lazy-load/#comment-219359">在早期的IE浏览器版本（如IE6）中会有无法解析的风险</a>，且影响某些特定情况下的缓存，但当使用修改后的YUI时，合并的URL变成类似<code>/min/b=yui&#038;f=3.1.1/tabview/assets/skins/sam/tabview.css,</code>的样子，就会出现bug了。对于YUI的Combo Handler来说这是一个小bug，所以<a href="http://yuilibrary.com/projects/yui3/ticket/2528680">YUI3把这个bug设置为P5</a>。但当我们改造YUI3来更好的支持Minify时，还要解决这个问题，具体方案请看示例<a href="http://dancewithnet.com/lab/2010/yui3-loader-and-minify/fixed.html">在修改后的YUI3中使用Minify</a>。</p>
<h3>在CDN上使用Minify</h3>
<p>CDN的全称是Content Delivery Network，即内容分发网络。其最常应用就是通过位于不同地理位置的服务器把静态资源部署到用户最近的边缘，这样能有效解决Web服务中大量静态资源的速度和性能问题。由于实施成本比较高，所以在实际的应用中，大型公司一般会组建自己的CDN，而小型公司只能租借第三方的CDN，但不管怎样这两种方式都不会影响在服务端实施合并和压缩程序。一般情况下，静态资源也并不是直接上传到CDN，而是先传到一台后台服务器，然后各地CDN的前端Cache服务器按需索取。YUI CDN的Combo Handler就是部署在其后台服务器上的，Minify也应如此。简单图示如下：<br /><img src="http://dancewithnet.com/wp-content/uploads/2010/06/cdn-and-minify.png" alt="" title="cdn-and-minify" width="678" height="201" class="alignnone size-full wp-image-1519" /></p>
<p>当一个资源请求到CDN时，CDN会先检查本地是否存在这个资源，如果有则会直接返回该资源，如果没有则会请求其后台服务器，后台服务器会依据资源URL的信息进行相应的处理，然后返回给CDN，CDN就会存储这个资源，再次出现这个资源请求时就无需请求后台服务器了。所以，虽然合并特别是压缩JavaScript和CSS文件是消耗时间的，但是由于只需要第一次，并且第一次基本上由我们自己访问掉（我们可以创建程序自动进行一次访问来保证，实际上图片优化也可以采用这种方式），所以基本上很安全。这正是目前在<a href="http://koubei.com">口碑网</a>实施的JavaScript和CSS合并方案，在<a href="http://www.slideshare.net/kavenyan/ss-2755539">第4届D2的《前端性能优化和自动化》</a>中也介绍了它。</p>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2010/06/08/minify-js-and-css-files-in-server/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>动态加载JavaScript的小实践</title>
		<link>http://dancewithnet.com/2009/11/05/a-little-practice-about-js-lazy-load/</link>
		<comments>http://dancewithnet.com/2009/11/05/a-little-practice-about-js-lazy-load/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 16:56:30 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Loader]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1488</guid>
		<description><![CDATA[动态加载JavaScript文件和CSS资源为Web前端开发提供了巨大的灵活性，同时也实现了lazy load和按需加载，相比XMLHttpRequest而言其没有跨域的限制使其广泛应用。其基本原理是：在页面DOMReady后，利用... ]]></description>
			<content:encoded><![CDATA[<p>动态加载JavaScript文件和CSS资源为Web前端开发提供了巨大的灵活性，同时也实现了lazy load和按需加载，相比XMLHttpRequest而言其没有跨域的限制使其广泛应用。其基本原理是：在页面DOMReady后，利用JavaScript把指定文件路径的script和link元素插入到页面中，然后判断其加载状态再进行继续操作。</p>
<p><span id="more-1488"></span></p>
<p><a href="http://developer.yahoo.com/yui/3/get/">YUI的Get</a>就专门提供了一套动态加载的机制，是YUI最基础的功能之一。在YUI中利用Get加载JavaScript和CSS资源会在HTML的head节点中插入如下代码：</p>
<pre><code>&lt;script id="..." type="text/javascript" src="some.js"&gt;&lt;/script&gt;
&lt;link id="..." type="text/css" rel="stylesheet" href="some.css"&gt;
</code></pre>
<p>当页面编码和JavaScript或CSS资源编码不一致时，常见的方法是通过charset属性声明其编码，比如页面是gb2312，而资源文件为utf-8，则设置编码后其插入的代码是</p>
<pre><code><span>//YUI3.0.0 和 YUI 2.8.0中</span>
&lt;script id="..." type="text/javascript" src="some.js" charset="utf-8"&gt;&lt;/script&gt;
&lt;link id="..." type="text/css" rel="stylesheet" href="some.css" charset="utf-8"&gt;
</code></pre>
<p>然而，<a href="http://dancewithnet.com/lab/2009/yui-loader-bug-in-ie/in-gb2312.html">在IE的一些特殊情况下加载JavaScript时，当你刷新页面时会看到状态栏上有如下的错误提示</a>：<br /><img src="http://dancewithnet.com/wp-content/uploads/2009/11/yui-loader-bug-in-ie.png" alt="YUI3.0.0动态加载JavaScript的bug" title="YUI3.0.0动态加载JavaScript的bug" width="593" height="460" class="alignnone size-full wp-image-1489" /></p>
<p>当你<a href="http://dancewithnet.com/lab/2009/yui-loader-bug-in-ie/random-in-gb2312.html">通过随机参数让JavaScript文件不缓存</a>时，或者<a href="http://dancewithnet.com/lab/2009/yui-loader-bug-in-ie/fixed-in-gb2312.html">让script元素中的charset属性位于src属性之前（比如利用YUI2.8.0之前版本加载）</a>就不会有这个错误提示。所以，这个问题可能是IE的缓存解码机制的bug，也可以看着是<a href="http://yuilibrary.com/projects/yui3/ticket/2528363">YUI的bug（已经提交给YUI开发团队，将在3.1.0中解决）</a>。</p>
<p>因此，动态添加script或CSS资源时，把charset放在资源路径前面是最佳实践。<a href="http://dancewithnet.com/lab/2009/yui-loader-bug-in-ie/fixed-in-gb2312.html">对于YUI，暂时可以这样修改源码来修复</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2009/11/05/a-little-practice-about-js-lazy-load/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>CSS实现HTML元素透明的那些事</title>
		<link>http://dancewithnet.com/2009/09/06/css-opacity/</link>
		<comments>http://dancewithnet.com/2009/09/06/css-opacity/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 15:44:00 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[HTML & CSS]]></category>
		<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[-ms-filter]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[hasLayout]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Mootools]]></category>
		<category><![CDATA[opacity]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1469</guid>
		<description><![CDATA[CSS3草案中定义了{opacity:&#60;length&#62; &#124; inherit;}来声明元素的透明度，这已经得到了大多数现代浏览器的支持，而IE则很早通过特定的私有属性filter来实现的，所以HTML元素的透明效果已经无处... ]]></description>
			<content:encoded><![CDATA[<p>CSS3草案中定义了<a href="http://www.w3.org/TR/css3-color/#transparency"><code>{opacity:&lt;length&gt; | inherit;}</code></a>来声明元素的透明度，这已经得到了大多数现代浏览器的支持，而IE则很早通过特定的私有属性<a href="http://msdn.microsoft.com/en-us/library/ms532967%28VS.85%29.aspx"><code>filter</code></a>来实现的，所以HTML元素的透明效果已经无处不在了。首先看看<a href="http://developer.yahoo.com/yui/articles/gbs/">A级浏览器</a>所支持的用<a href="https://developer.mozilla.org/en/CSS/opacity">CSS实现元素透明的方案</a>：</p>
<p><span id="more-1469"></span></p>
<table>
<tr>
<th>浏览器</th>
<th>最低<br />版本</th>
<th>方案</th>
</tr>
<tr>
<th rowspan="3">Internet Explorer</th>
<td>4.0</td>
<td><code>filter: alpha(opacity=xx);</code></td>
</tr>
<tr>
<td>5.5</td>
<td><code>filter: progid:DXImageTransform.Microsoft.Alpha(opacity=xx);</code>
</td>
</tr>
<tr>
<td>8.0</td>
<td><code>filter: "alpha(opacity=xx)";<br />
filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=xx)";<br />
-ms-filter: "alpha(opacity=xx)";<br />
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=30)";</code>
</td>
</tr>
<tr>
<th>Firefox (Gecko)</th>
<td>0.9 (1.7)</td>
<td><code>opacity</code></td>
</tr>
<tr>
<th>Opera</th>
<td>9.0</td>
<td><code>opacity</code></td>
</tr>
<tr>
<th>Safari (WebKit)</th>
<td>1.2 (125)</td>
<td><code>opacity</code></td>
</tr>
</table>
<p>实际上在IE8中，-ms-filter是filter的别名，两者区别是<a href="http://msdn.microsoft.com/en-us/library/ms530752%28VS.85%29.aspx">-ms-filter的属相值必须被单引号或双引号包围</a>，而filter中则不是必须，而在IE8之前的版本中，filter的属性值必须不被单引号或双引号包围。</p>
<p id="hasLayout">IE中的HTML元素要实现透明，则其必须具备layout，这样的元素有仅可读的属性<a href="http://msdn.microsoft.com/en-us/library/ms530764%28VS.85%29.aspx">hasLayout</a>，且其值为true。具体情况如下：</p>
<ol>
<li><code>body</code>、<code>img</code>、<code>table</code>、<code>tr</code>、<code>th</code>、<code>td</code>等元素的<code>hasLayout</code>一直为<code>true</code>。</li>
<li><code>type</code>为<code>text</code>、<code>button</code>、<code>file</code>或<code>select</code>的<code>input</code>的<code>hasLayout</code>一直为<code>true</code>。</li>
<li>设置<code>{position:absolute}</code>的元素的<code>hasLayout</code>为<code>true</code></li>
<li>设置<code>{float:left|right}</code>的元素的<code>hasLayout</code>为<code>true</code></li>
<li>设置<code>{display:inline-block}</code>的元素的<code>hasLayout</code>为<code>true</code></li>
<li>设置<code>{height:xx}</code>或<code>{width:xx}</code>的元素必须具体以下两个条件之一，其<code>hasLayout</code>才能为<code>true</code>：
<ol>
<li>IE8兼容模式和IE8以前的浏览器中，在标准(strict)模式下其<code>display</code>的值是<code>block</code>，如<a href="http://dancewithnet.com/lab/2009/css-opacity/#demo3">demo3</a>就不行。</li>
<li>元素在怪癖模式（compat mode）下。</li>
</ol>
</li>
<li>设置了<code>{zoom:xx}</code>的元素在IE8的兼容模式或IE8之前的浏览器中其<code>hasLayout</code>为<code>true</code>，但在IE8的标准模式下则不会触发<code>hasLayout</code>。</li>
<li>设置了<code>{writing-mode:tb-rl}</code>的元素的<code>hasLayout</code>为<code>true</code>。</li>
<li>元素的<a href="http://msdn.microsoft.com/en-us/library/ms537837%28VS.85%29.aspx"><code>contentEditable</code></a>的属性值为<code>true</code>。</li>
<li>在IE8标准模式下设置了<code>{display:block}</code>的元素的<code>hasLayout</code>一直为<code>true</code>，如<a href="http://dancewithnet.com/lab/2009/css-opacity/#demo8">demo8</a>。</li>
</ol>
<p>关于hasLayout的更多详情可以看<a href="http://msdn.microsoft.com/en-us/library/bb250481%28VS.85%29.aspx">Exploring Internet Explorer &#8220;HasLayout&#8221; Overview</a>和<a href="http://www.satzansatz.de/cssd/onhavinglayout.html">On having layout</a></p>
<p>从上面就可以看出IE实现HTML元素的透明如此混乱，为了向下兼容和自己的私有属性让IE上实现元素透明有多种方式，比如<a href="http://dancewithnet.com/lab/2009/css-opacity/" class="link-btn">CSS Opacity实例中的demo1到demo8</a>，虽然<a href="http://blogs.msdn.com/ie/archive/2008/09/08/microsoft-css-vendor-extensions.aspx">IE团队推荐实现透明的方式</a>是：</p>
<pre><code>{
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
  filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
  opacity: .5;
}</code></pre>
<p>而目前简单最好用的实现方式是<a href="http://dancewithnet.com/lab/2009/css-opacity/" class="link-btn">如CSS Opacity中demo4这样</a>：</p>
<pre><code>{
    filter:alpha(opacity=30);
    opacity:.3;
}</code></pre>
<p>实际上目前最流行的JavaScript框架的设置样式方法都是应用这种方式，并且针对IE设置了<code>{zoom:1}</code>来让元素的<code>hasLayout</code>为<code>true</code>，但在IE8的标准模式下<code>zoom</code>并不能触发<code>hasLayout</code>，所以利用它们设置<code>hasLayout</code>为<code>false</code>的元素的透明度时在IE8的标准模式下是失败的，这个bug在<a href="http://developer.yahoo.com/yui/">YUI</a><ins datetime="2009-09-09T09:38:41+08:00">（我已经给YUI团队提交了这个bug，他们会在<a href="http://yuilibrary.com/projects/yui2/ticket/2528440">下个版本修复</a>，最新的2.8.0中依旧存在，期待2.9.0吧）</ins>、<a href="http://prototypejs.org">Prototype</a>、<a href="http://jquery.com">jQuery</a>和<a href="http://mootools.net">Mootools</a>的最新版本中都存在，具体请在IE8标准模式下看<a href="http://dancewithnet.com/lab/2009/css-opacity/#demo9">demo9到demo11</a>。同样由于在IE8中设置透明度的方式多种多样，所以利用JavaScript获取HTML元素的透明度值需要考虑多种情况，YUI完美解决了这个问题，Prototype比jQuery稍微周全一点，而Mootools直接是<a href="https://mootools.lighthouseapp.com/projects/2706/tickets/707-getstyleopacity-always-returns-1">bug</a>，具体可以<a href="http://dancewithnet.com/lab/2009/css-opacity/" class="link-btn">在IE下看demo1到demo8</a>的演示。从这个角度给4个框架来个排名的话，YUI第一、Prototype第二、jQuery第三、Mootools垫底。</p>
<p>我简单的实现了设置和获取Opacity的函数，可以避开上面框架存在的bug，请<a href="http://dancewithnet.com/lab/2009/css-opacity/#demo12" class="link-btn">在IE8标准模式下看demo12</a>：</p>
<pre><code><span>//设置CSS opacity 属性的函数，解决IE8的问题</span>
var setOpacity = function(el,i){
  if(window.getComputedStyle){<span>// for non-IE</span>
    el.style.opacity = i;
  }else if(document.documentElement.currentStyle){ <span>// for IE</span>
    if(!el.currentStyle.hasLayout){
      el.style.zoom = 1;
    }
    if(!el.currentStyle.hasLayout){ <span>//在IE8中zoom不生效，所以再次设置inline-block</span>
      el.style.display = 'inline-block';
    }
    try{
      <span>//测试是否已有filter
      //http://msdn.microsoft.com/en-us/library/ms532847%28VS.85%29.aspx</span>
      if(el.filters){
        if(el.filters('alpha')){
	  el.filters('alpha').opacity = i * 100;
	}else{
	  el.style.filter += 'alpha(opacity='+ i * 100 +')';
	 }
       }
    }catch(e){
      el.style.filter = 'alpha(opacity='+ i * 100 +')';
    }
  }
}

<span>//获取CSS opacity 属性值的函数</span>
<span>//借鉴自http://developer.yahoel.com/yui/docs/YAHOO.util.Dom.html#method_getStyle</span>
var getOpacity = function(el){
  var value;
  if(window.getComputedStyle){
    value = el.style.opacity;
    if(!value){
      value = el.ownerDocument.defaultView.getComputedStyle(el,null)['opacity'];
    }
    return value;
  }else if(document.documentElement.currentStyle){
    value = 100;
    try { // will error if no DXImageTransform
        value = el.filters['DXImageTransform.Microsoft.Alpha'].opacity;
    } catch(e) {
        try { // make sure its in the document
            value = el.filters('alpha').opacity;
        } catch(err) {
        }
    }
    return value / 100;
  }
}
</code></pre>
<p>不得不说，这些事都是IE整出来的……</p>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2009/09/06/css-opacity/feed/</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>在HTML中获取正确的URL属性值</title>
		<link>http://dancewithnet.com/2009/07/27/get-right-url-from-html/</link>
		<comments>http://dancewithnet.com/2009/07/27/get-right-url-from-html/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 15:57:23 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[getAttribute]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[URL]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1462</guid>
		<description><![CDATA[在HTML中，常见的URL有多种表示方式：
相对URL：
    example.php
    demo/example.php
    ./example.php
    ../../example.php
    /example.php
绝对URL：

http://dancewithnet.com/example.php

http://dancewithnet.com:80/example.php

https:... ]]></description>
			<content:encoded><![CDATA[<p>在HTML中，常见的URL有多种表示方式：</p>
<pre><code>相对URL：
    example.php
    demo/example.php
    ./example.php
    ../../example.php
    /example.php
绝对URL：

http://dancewithnet.com/example.php

http://dancewithnet.com:80/example.php

https://dancewithnet.com/example.php</code></pre>
<p>同时HTML中有大量的元素属性值为URL，一般利用JavaScript获取这些URL属性值有两种方法：</p>
<p><span id="more-1462"></span></p>
<pre><code>&lt;a href="example.php" id="example-a"&gt;此时页面绝对URL是http://dancewithnet.com/&lt;/a&gt;
&lt;script&gt;
var oA = document.getElementById('example-a');
oA.href ==  'http://dancewithnet.com/example.php';
oA.getAttribute('href') == 'example.php';
&lt;/script&gt;
</code></pre>
<p>我们希望通过直接访问属性的方式得到完整绝对URL，通过getAttribute方法得到其原始的属性值，实际上这是一个比较理想的结果，在所有的A级浏览器中，能顺利得到这个结果的只有Firefox和IE8，其他浏览器都或多或少特殊情况，具体哪些元素的属性存在什么样的情况请看<a href="http://dancewithnet.com/lab/2009/get-right-url-from-html/index.html" class="link-btn">演示实例</a>。</p>
<p>在大部分浏览器中存在的问题是，两种方式都返回的是原始属性值，而实际应用中往往需要的是其绝对的URL，<a href="http://www.sitepoint.com/blogs/2007/08/10/dealing-with-unqualified-href-values/">《Dealing with unqualified HREF values》</a>中的解决方案太过于复杂，这里提供一种相对简单的解决方案，如果不考虑区别浏览器代码会非常简单：</p>
<pre><code>&lt;form action="example.php" id="example-form"&gt;
此时页面绝对URL是http://dancewithnet.com/&lt;/form&gt;
&lt;script>
var oForm = document.getElementById('example-form');

<span>//IE6、IE7、Safari、Chrome、Opera</span>
oForm.action ==  'example.php';
oForm.getAttribute('action') == 'example.php';

<span>//获取绝对URL的通用解决方案</span>
getQualifyURL(oForm,'action') == 'http://dancewithnet.com/example.php';

getQualifyURL = function(oEl,sAttr){
  var sUrl = oEl[sAttr],
      oD,
      bDo = false;
  <span>//是否是IE8之前版本
  //http://www.thespanner.co.uk/2009/01/29/detecting-browsers-javascript-hacks/
  //http://msdn.microsoft.com/en-us/library/7kx09ct1%28VS.80%29.aspx
  /*@cc_on
    try{
      bDo = @_jscript_version < 5.8 ?true : @false;
    }catch(e){
      bDo = false;
    }
  @*/
  //如果是Safari、Chrome和Opera</span>
  if(/a/.__proto__=='//' || /source/.test((/a/.toString+''))
                               || /^function \(/.test([].sort)){
    bDo = true;
  }
  if(bDo){
    oD = document.createElement('div');
    <span>/*
    //DOM 操作得到的结果不会改变
    var oA = document.createElement('a');
    oA.href = oEl[sAttr];
    oD.appendChild(oA);
    */</span>
    oD.innerHTML = ['&lt;a href="',sUrl,'"&gt;&lt;/a&gt;'].join('');
    sUrl = oD.firstChild.href;
  }
  return sUrl;
}
&lt;/script&gt;
</code></pre>
<p>在IE6和IE7这两个史前的浏览器身上还有一些更有意思的事情，两种方法在HTML元素A、AREA和IMG获取的属性值都是绝对URL，幸好<a href="http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx">微软为getAttribute提供了第二个参数</a>可以解决这个问题，同时还可以对IFEAM和LINK元素解决前面提到的两种方法都返回原始属性的问题：</p>
<pre><code>&lt;link href="../../example.css" id="example-link"&gt;
&lt;a href="example.php" id="example-a"&gt;此时页面绝对URL是http://dancewithnet.com/&lt;/a&gt;

&lt;script&gt;
var oA = document.getElementById('example-a'),
     oLink = document.getElementById('example-link');

oA.href ==  'http://dancewithnet.com/example.php';
oA.getAttribute('href') == 'http://dancewithnet.com/example.php';
oA.getAttribute('href',2) == 'example.php';

oLink.href ==  'example.php';
oLink.getAttribute('href') == 'example.php';
oLink.getAttribute('href',4) == 'http://dancewithnet.com/example.php';
&lt;/script&gt;
</code></pre>
<p><ins datetime="2011-01-11T1:14:46+08:00">今天突然看到<a href="http://oldj.net/article/js-href-url-encode-ie6/">getAttribute(&#8216;href&#8217;,2)还能解决获取IE6下中文URL的乱码问题</a>，虽然以前没有遇到过，但作为针对IE6怪癖的记录还是值得了解的。</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2009/07/27/get-right-url-from-html/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>《JavaScript语言精粹》</title>
		<link>http://dancewithnet.com/2009/04/02/javascript-the-good-parts/</link>
		<comments>http://dancewithnet.com/2009/04/02/javascript-the-good-parts/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 15:45:57 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[Douglas Crockford]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[书评]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/2009/04/02/javascript-the-good-parts/</guid>
		<description><![CDATA[本书的作者Douglas Crockford是JavaScript开发社区最知名的权威，JavaScript的发明人Brendan Eich说他是“Yoda of lambda programming and JavaScript（lambda编程和JavaScript的精神领袖）”。他不仅仅给我们带来了JSON、... ]]></description>
			<content:encoded><![CDATA[<p>本书的作者<a href="http://dancewithnet.com/2009/03/29/douglas-crockford/">Douglas Crockford</a>是JavaScript开发社区最知名的权威，JavaScript的发明人Brendan Eich说他是“Yoda of lambda programming and JavaScript（lambda编程和JavaScript的精神领袖）”。他不仅仅给我们带来了JSON、JSLint、JSMin和ADSafe等等在JavaScript开发领域应用广泛且影响深远的作品，更重要的是给我们带来了受益终身的利用JavaScript进行高效开发的思想和风格，这就是本书的重要意义。</p>
<p>JavaScript曾是“世界上最被误解的语言”，因为它担负太多的特性，包括糟糕的交互和失败的设计，但随着Ajax的到来，JavaScript“从最受误解的编程语言演变为最流行的语言”，这除了幸运之外，至少还说明它是一个不错的语言。Douglas Crockford在这本书中剥除JavaScript糟糕的外衣，抽离出一个具有更好可靠性、可读性和可维护性的JavaScript子集，让你看到一门优雅的、轻量级的和非常富有表现力的语言。他从语法、对象、函数、继承、数组、正则表达式、方法、样式和优美的特性这9个方面来呈现这门语言真正的精华，这是语言最本质最优雅的部分，通过它们完全可以构建出高效的代码。他还通过附录列出了这门语言的糟粕和鸡肋部分，且告诉你如何避免它们。最后还介绍了JSLint，通过它的检验，能有效的保障我们写出优美高效的代码。</p>
<p><span id="more-1445"></span>
<p>这是一本厚积薄发“薄”大精深的书籍，Douglas Crockford仅仅用了160页来道出JavaScript的语言本质，值得任何正在或者想从事JavaScript开发的人阅读，并且非常需要反复阅读。学习、理解、实践大师的思想，我们才可能站在巨人的肩上，才有机会超越大师，这本书就是开始。</p>
<p>我很高兴和淘宝UED的前端主管小马（赵泽欣）一起来翻译这本书，去年近5个月的翻译时间是一个非常艰苦而又痛快的学习过程。我们冒着“犯罪”的危险完成了翻译，现在我也很惶恐的推荐给大家，希望我们的努力能让读者读出本书的精华，更要读懂JavaScript的语言精华。</p>
<p>感谢你的关注、阅读、建议和批评。</p>
<ol>
<li><a href="http://www.china-pub.com/195292">购买《JavaScript语言精粹》</a></li>
<li>样章阅读
<ol>
<li><a href="http://images.china-pub.com/ebook195001-200000/195292/ch01.pdf">第一章. 精华</a></li>
<li><a href="http://images.china-pub.com/ebook195001-200000/195292/ch10.pdf">第十章. 优美的特性</a></li>
</ol>
</li>
<li><a href="http://dancewithnet.com/javascript-the-good-parts-errata/">勘误表</a></li>
<li><a href="http://ued.taobao.com/blog/2009/04/02/javascript_good_part_tw/">淘宝UED Blog：《JavaScript语言精粹》译者序及样章试读</a></li>
<li><a href="http://dancewithnet.com/2009/03/29/douglas-crockford/">JavaScript大牛：Douglas Crockford</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2009/04/02/javascript-the-good-parts/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>JavaScript大牛：Douglas Crockford</title>
		<link>http://dancewithnet.com/2009/03/29/douglas-crockford/</link>
		<comments>http://dancewithnet.com/2009/03/29/douglas-crockford/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 14:07:46 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[互联网 & IT]]></category>
		<category><![CDATA[Douglas Crockford]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[牛人]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/2009/03/29/douglas-crockford/</guid>
		<description><![CDATA[Douglas Crockford是JavaScript开发社区最知名的权威，是JSON、JSLint、JSMin和ADSafe之父，是《JavaScript：The Good Parts》（英文版、中文版）的作者。JavaScript的发明人Brendan Eich说他是“Yoda of lambda programming a... ]]></description>
			<content:encoded><![CDATA[<p>Douglas Crockford是JavaScript开发社区最知名的权威，是<a href="http://www.json.org/json-zh.html">JSON</a>、<a href="http://www.jslint.com/">JSLint</a>、<a href="http://www.crockford.com/javascript/jsmin.html">JSMin</a>和<a href="http://www.adsafe.org/">ADSafe</a>之父，是《JavaScript：The Good Parts》（<a href="http://www.china-pub.com/43541">英文版</a>、<a href="http://www.china-pub.com/195292">中文版</a>）的作者。<a href="http://zh.wikipedia.org/wiki/Brendan_Eich">JavaScript的发明人Brendan Eich</a>说他是“<a href="http://zh.wikipedia.org/w/index.php?title=尤達&amp;variant=zh-cn">Yoda</a> of <a href="http://zh.wikipedia.org/wiki/&Lambda;演算">lambda</a> programming and JavaScript（lambda编程和JavaScript的精神领袖）”。他同时也服务于<a href="http://zh.wikipedia.org/w/index.php?title=Ecma国际&amp;variant=zh-cn">ECMA</a>的JavaScript2.0技术委员会（TC39）。其个人站点和Blog是<a href="http://www.crockford.com/">http://www.crockford.com/</a>和<a href="http://profiles.yahoo.com/blog/GSBHPXZFNRM2QRAP3PXNGFMFVU">http://profiles.yahoo.com/blog/GSBHPXZFNRM2QRAP3PXNGFMFVU</a>。</p>
<p>Douglas Crockford现在是Yahoo的资深JavaScript架构师，曾在<a href="http://zh.wikipedia.org/w/index.php?title=Atari&amp;variant=zh-cn">Atari</a>公司（视频游戏工业的领袖）开发了办公自动化系统，同时也完成了对于游戏和音乐的研究；曾任<a href="http://en.wikipedia.org/wiki/Lucasfilm">Lucasfilm（卢卡斯）电影公司</a>技术总监；在<a href="http://zh.wikipedia.org/w/index.php?title=派拉蒙電影公司&amp;variant=zh-cn">Paramount（派拉蒙）公司</a>任职过新媒体执行主管；在电气社区，通常为人所知的是communities.com的创始人兼首席执行官；他还创办了State软件公司并作为该公司CTO，这也是他发现JSON时所在的地方。他同时也对<a href="http://en.wikipedia.org/wiki/Blissymbolics">Blissymbolics</a>非常感兴趣，这是一种图形、象征性的语言，并且对<a href="http://crockford.com/pwl/">永久减肥（Permanent Weight Loss）</a>做过研究。</p>
<p><span id="more-1442"></span>
<p><a href="http://yuilibrary.com/">YUI</a>团队2008年底的合影，中间的长者即为Douglas Crockford：<a href="http://www.flickr.com/photos/equanimity/2126487011/sizes/l/"><img src="http://dancewithnet.com/wp-content/uploads/2009/03/yui-team.jpg" alt="yui-team" title="yui-team" width="500" height="337" class="alignnone size-full wp-image-1443" /></a></p>
<p>Douglas Crockford作为JavaScript开发社区的Guru，其众多的在JavaScript开发方面的研究成果被广泛的应用，而他的思想也深深的影响了整个JavaScript应用和发展。学习、理解、实践大师的思想，我们才可能站在巨人的肩上，才有机会超越，所以下面列表是一个开始：</p>
<ol>
<li><a href="http://javascript.crockford.com/javascript.html">JavaScript: The Wrrrld&#8217;s Most Misunderstood Programming Language</a>       <br />中文：<a href="http://shiningray.cn/javascript-the-worlds-most-misunderstood-programming-language.html">JavaScript:世界上最被误解的语言</a> </li>
<li><a href="http://javascript.crockford.com/popular.html">The World&#8217;s Most Misunderstood Programming Language Has Become the World&#8217;s Most Popular Programming Language</a>       <br />中文：<a href="http://www.ajaxjs.com/popular.htm">JavaScript：从最受误解的编程语言演变为最流行的语言</a> </li>
<li><a href="http://www.crockford.com/html/">A Survey of the JavaScript Programming Language</a>       <br />中文：<a href="http://svza.blogspot.com/2007/03/javascript_09.html">纵览 JavaScript语言</a> </li>
<li><a href="http://javascript.crockford.com/code.html">Code Conventions for the JavaScript Programming Language</a>       <br />中文：<a href="http://dancewithnet.com/snapshot/code-conventions-for-the-javascript-programming-language/">JavaScript程序编码规范</a> </li>
<li><a href="http://javascript.crockford.com/little.html">The Little JavaScripter</a>       <br />对《The Little Schemer》一书的讨论，并作了以JavaScript代替Scheme的尝试 </li>
<li><a href="http://javascript.crockford.com/private.html">Private Members in JavaScript</a>       <br />中文：<a href="http://shiningray.cn/private-members-in-javascript.html">JavaScript中的私有成员</a> </li>
<li><a href="http://javascript.crockford.com/prototypal.html">Prototypal Inheritance in JavaScript</a>       <br />中文：<a href="http://svza.blogspot.com/2007/03/javascript_14.html">在JavaScript实现基于原型的继承</a> </li>
<li><a href="http://www.crockford.com/html/">Classical Inheritance in JavaScript</a>       <br />中文：<a href="http://svza.blogspot.com/2007/03/javascript_4663.html">在JavaScript中实现基于类模式的继承</a> </li>
<li><a href="http://javascript.crockford.com/remedial.html">Remedial JavaScript</a>       <br />过快的标准化导致JavaScript在开发过程中未得到足够的优化，当前它仍存在一些问题，本文提出了一些补救的措施 </li>
<li><a href="http://javascript.crockford.com/script.html">JavaScript and HTML Script Tags</a>       <br />中文：<a href="http://www.dreamdu.com/blog/2008/08/08/script/">JavaScript与HTML的Script标签</a> </li>
<li><a href="http://javascript.crockford.com/memory/leak.html">JScript Memory Leaks</a>       <br />中文：<a href="http://svza.blogspot.com/2007/06/jscript.html">JScript的内存泄漏</a> </li>
<li><a href="http://javascript.crockford.com/tdop/tdop.html">Top Down Operator Precedence</a>       <br />自顶向下的运算符优先级，这是Douglas Crockford为<a href="http://www.china-pub.com/37838">《Beautiful Code（代码之美）》</a>而写，位于书中第九章 </li>
<li><a href="http://javascript.crockford.com/style1.html">The Elements of JavaScript Style, Parts One</a> and <a href="http://javascript.crockford.com/style2.html">Two</a>       <br />中文：<a href="http://dancewithnet.com/2008/01/26/the-elements-of-javascript-style-part-one/">JavaScript的风格要素1</a>和<a href="http://dancewithnet.com/2008/01/30/the-elements-of-javascript-style-part-two/">2</a> </li>
<li><a href="http://dancewithnet.com/snapshot/minification-v-obfuscation/">Minification v. Obfuscation</a> </li>
<li><a href="http://dancewithnet.com/snapshot/synchronous-v-asynchronous/">Synchronous v. Asynchronous</a> </li>
<li><a href="http://dancewithnet.com/snapshot/with-statement-considered-harmful/">with Statement Considered Harmful</a> </li>
<li><a href="http://dancewithnet.com/snapshot/global-domination/">Global Domination</a> </li>
<li><a href="http://dancewithnet.com/snapshot/global-domination-part-two/">Global Domination, Part Two</a> </li>
<li><a href="http://dancewithnet.com/snapshot/for-in-intrigue/">for in Intrigue</a> </li>
<li><a href="http://dancewithnet.com/snapshot/javascript-we-hardly-new-ya/">JavaScript, We Hardly new Ya</a>       <br />中文：<a href="http://ued.taobao.com/blog/2007/05/15/%E4%BD%A0%E7%9C%9F%E7%9A%84%E4%BC%9A%E5%86%99javascript%E5%90%97%EF%BC%9F/">JavaScript的new，好久不见啊</a> </li>
<li><a href="http://dancewithnet.com/snapshot/json-and-browser-security/">JSON and Browser Security</a>       <br />中文：<a href="http://www.javaeye.com/topic/95569">JSON和浏览器安全</a> </li>
<li><a href="http://dancewithnet.com/snapshot/id-rather-switch-than-fight/">I’d Rather switch Than Fight!</a> </li>
<li><a href="http://dancewithnet.com/snapshot/premature-standardization/">The Only Thing We Have To Fear Is Premature Standardization</a>       <br />中文：<a href="http://ued.taobao.com/blog/2008/08/15/the_only_thing_we_have_to_fear_is_premature_standardization/">不成熟的标准化是我们唯一惧怕的</a> </li>
<li><a href="http://dancewithnet.com/snapshot/when-you-cant-count-on-your-numbers/">When You Can&#8217;t Count On Your Numbers</a> </li>
<li><a href="http://www.crockford.com/html/">Fixing HTML</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://sp42.javaeye.com/blog/145268">中文</a> </li>
<li><a href="http://profiles.yahoo.com/blog/GSBHPXZFNRM2QRAP3PXNGFMFVU?eid=r4TzWT86mnkHWVlA8n1uJxy4n8o1AFAHZgOFD4swhgwmbEsz9Q">HTML4.2</a> </li>
<li><a href="http://www.slideshare.net/douglascrockford/ajax-security-255587">Ajax security</a><sup>幻灯片</sup> </li>
<li>JavaScript: The Good Parts</a><sup>视频，2009.03在Google的演讲</sup>：
<ol>
<li><a href="http://google-code-updates.blogspot.com/2009/03/doug-crockford-javascript-good-parts.html">38 minutes</a><sup>视频位于Youtube上</sup> </li>
<li><a href="http://www.slideshare.net/rajivmordani/good-parts-of-javascript-douglas-crockford-presentation">幻灯片</a><sup>和ajax world 2008版本一样</sup> </li>
</ol>
</li>
<li>The Mashup Problem and Google Gears<sup>视频</sup></a>
<ol>
<li><a href="http://video.google.com/videoplay?docid=452089494323007214">44 minutes</a> | <a href="http://vp.video.google.com/videodownload?version=0&amp;secureurl=TgAAAI8fZJkCVfmUhmWs1sp-jHVMpmbggk2J4l6edqJ46szRcc1EuI-SIMFbF54vyJfvcF4wjN2LJW1gLuXc6NP4VYujbDM87GKIfh-5R5Ppo0Ga&amp;sigh=287gGBtLhHoYSTDCpAZGISu7TFE">MP4 download</a> </li>
</ol>
</li>
<li>The JavaScript Programming Language<sup>视频</sup>：
<ol>
<li><a href="http://video.yahoo.com/video/play?vid=111593">Part 1: 31 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-1.m4v">M4V download</a> </li>
<li><a href="http://video.yahoo.com/video/play?vid=111594">Part 2: 31 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-2.m4v">M4V download</a> </li>
<li><a href="http://video.yahoo.com/video/play?vid=111595">Part 3: 29 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-3.m4v">M4V download</a> </li>
<li><a href="http://video.yahoo.com/video/play?vid=111596">Part 4: 20 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-4.m4v">M4V download</a> </li>
<li><a href="http://www.slideshare.net/guestceb98b/the-javascript-programming-language">幻灯片</a> </li>
</ol>
</li>
<li>An Inconvenient API: The Theory of the Dom<sup>视频</sup>：
<ol>
<li><a href="http://video.yahoo.com/video/play?vid=111582">Part 1 (31 minutes)</a> </li>
<li><a href="http://video.yahoo.com/video/play?vid=111583">Part 2 (21 minutes)</a> </li>
<li><a href="http://video.yahoo.com/video/play?vid=111584">Part 3 (26 minutes)</a> </li>
<li><a href="http://www.slideshare.net/kavenyan/the-theory-of-the-dom">幻灯片</a> </li>
</ol>
</li>
<li>Advanced JavaScript<sup>视频</sup>：
<ol>
<li><a href="http://video.yahoo.com/video/play?vid=111585">Part 1: 31 minutes</a> </li>
<li><a href="http://video.yahoo.com/video/play?vid=111586">Part 2: 25 minutes</a> </li>
<li><a href="http://video.yahoo.com/video/play?vid=111587">Part 3: 11 minutes</a> </li>
<li><a href="http://www.slideshare.net/Adieu/advanced-javascript">幻灯片</a> </li>
</ol>
</li>
<li>Quality<sup>视频，YAHOO Frontend Summit 2007</sup>：
<ol>
<li><a href="http://video.yahoo.com/watch/529579/2724346">48 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-quality.m4v">M4V download</a> </li>
</ol>
</li>
<li>JavaScript: The Good Stuff<sup>视频</sup>：
<ol>
<li><a href="http://video.yahoo.com/watch/630959/2974197">39 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-goodstuff.m4v">M4V download</a> </li>
</ol>
</li>
<li>The State of Ajax<sup>视频</sup>：
<ol>
<li><a href="http://video.yahoo.com/watch/1382941/4760685">38 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/stateofajax.m4v">M4V download</a> </li>
</ol>
</li>
<li>Ajax Performance<sup>视频</sup>：
<ol>
<li><a href="http://video.yahoo.com/watch/4156174/11192533">38 minutes</a> | <a href="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-performance.m4v">M4V download</a> </li>
<li><a href="http://www.slideshare.net/kavenyan/ajax-performance">幻灯片</a> </li>
<li>誊本：<a href="http://dancewithnet.com/snapshot/douglas-crockford-ajax-performance/">英文</a>、<a href="http://blog.360.yahoo.com/blog-sOW1QOA9crUyOdXFxOeK4xc-?cq=1&amp;p=200">中文</a> </li>
</ol>
</li>
<li>The JSON Saga
<ol>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockford-json">38 minutes</a> | <a href="http://yuiblog.com/yuitheater/crockford-json.m4v">M4V download</a> </li>
<li><a href="http://www.slideshare.net/kavenyan/the-json-saga">幻灯片</a></li>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockford-json">誊本</a></li>
</ol>
</li>
<li>
The State and Future of JavaScript</p>
<ol>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockford-yuiconf2009-state">55 minutes</a> | <a href="http://yuiblog.com/yuitheater/crockford-yuiconf2009-state.m4v">M4V download</a> </li>
<li><a href="http://www.yuiblog.com/assets/crockford-yuiconf2009-stateandfuture.ppt">幻灯片</a></li>
</ol>
</li>
<li><a href="http://yuiblog.com/crockford/">On JavaScript</a>
<ol>
<li>Volume One: The Early Years <sup>(Monday, January 25, 2010)</sup>
<ol>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-1">90 minutes</a> | <a href="http://yuiblog.com/yuitheater/crockonjs-1.m4v">M4V download</a> </li>
<li><a href="http://www.slideshare.net/douglascrockford/crockford-on-javascript-volume-one-the-early-years">幻灯片</a></li>
</ol>
</li>
<li>Chapter 2: And Then There Was JavaScript <sup>(Friday, February 5, 2010)</sup>
<ol>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-2">90 minutes</a> | <a href="http://yuiblog.com/yuitheater/crockonjs-2.m4v">M4V download</a> </li>
<li><a href="http://www.slideshare.net/douglascrockford/crockford-on-javascript-chapter-2-and-then-there-was-javascript">幻灯片</a></li>
</ol>
</li>
<li>Act III: Function the Ultimate <sup>(Wednesday, February 17, 2010)</sup>
<ol>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-3">73 minutes</a> | <a href="http://yuiblog.com/yuitheater/crockonjs-3.m4v">M4V download</a> </li>
<li><a href="http://www.slideshare.net/douglascrockford/crockford-on-javascript-act-iii-function-the-ultimate">幻灯片</a></li>
</ol>
</li>
<li>Episode IV: The Metamorphosis of Ajax <sup>(Wednesday, March 3, 2010)</sup>
<ol>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-4">93 minutes</a> | <a href="http://yuiblog.com/yuitheater/crockonjs-4.m4v">M4V download</a> </li>
<li><a href="http://www.slideshare.net/douglascrockford/crockford-on-javascript-episode-iv-the-metamorphosis-of-ajax">幻灯片</a></li>
</ol>
</li>
<li>Part 5: The End of All Things <sup>(Wednesday, March 31, 2010)</sup>
<ol>
<li><a href="http://developer.yahoo.com/yui/theater/video.php?v=crockonjs-5">94 minutes</a> | <a href="http://yuiblog.com/yuitheater/crockonjs-5.m4v">M4V download</a> </li>
<li><a href="http://yuiblog.com/assets/crockonjs-5.pdf">幻灯片</a></li>
</ol>
</li>
</ol>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2009/03/29/douglas-crockford/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
<enclosure url="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-2.m4v" length="139907805" type="video/x-m4v" />
<enclosure url="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-1.m4v" length="139301206" type="video/x-m4v" />
<enclosure url="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-3.m4v" length="135133974" type="video/x-m4v" />
<enclosure url="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-tjpl-4.m4v" length="90013380" type="video/x-m4v" />
<enclosure url="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-quality.m4v" length="192768058" type="video/x-m4v" />
<enclosure url="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-goodstuff.m4v" length="172337121" type="video/x-m4v" />
<enclosure url="http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yui/theater/crockford-performance.m4v" length="195027943" type="video/x-m4v" />
		</item>
		<item>
		<title>如何开始使用YUI Doc工具？</title>
		<link>http://dancewithnet.com/2008/12/30/why-start-yui-doc/</link>
		<comments>http://dancewithnet.com/2008/12/30/why-start-yui-doc/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 16:42:59 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[yuidoc]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1418</guid>
		<description><![CDATA[YUI Team实践出了一个高效易协作的前端代码开发流程：代码首先由Ant来组织管理和版本化、接着由JsLint来验证，然后由YUI Doc文档化、最后由YUI Compressor进行压缩发布。上个月初，YUI Team公布了这... ]]></description>
			<content:encoded><![CDATA[<p>YUI Team实践出了一个高效易协作的前端代码开发流程：代码首先由Ant来组织管理和版本化、接着由<a href="http://www.jslint.com/">JsLint</a>来验证，然后由<a href="http://developer.yahoo.com/yui/yuidoc/">YUI Doc</a>文档化、最后由<a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a>进行压缩发布。上个月初，YUI Team公布了这个新的JavaScript API文档生成工具<a href="http://developer.yahoo.com/yui/yuidoc/">YUI Doc</a>，它本来专门为<a href="http://developer.yahoo.com/yui/">YUI</a>提供<a href="http://developer.yahoo.com/yui/docs/">API级别的文档</a>的，现在它开源为人民服务了。</p>
<p>YUI Doc和JavaDoc、JSDoc和<a href="http://code.google.com/p/jsdoc-toolkit/">JsDoc Toolkit</a>相似。YUI Doc是由注解驱动（comment-driven ）的系统，它通过解析代码中描述结构的注解来生成文档。由于它纯粹的依赖于注解，所以并不像一些模拟系统一样需要有惯用语和代码模式。更详细的介绍可以看<a href="http://developer.yahoo.com/yui/yuidoc/">YUI Doc的官方文档</a>和YUI blog上的《YUI Doc: A New Tool for Generating JavaScript API Documentation》（由于YUI blog咱们无法访问，比较好的解决方案就是在Google Reader中订阅它的Feed，直接输入 http://yuiblog.com即可。）</p>
<p>YUI Doc是基于Python开发，且依赖几个扩展库，加之其<a href="http://developer.yahoo.com/yui/yuidoc/#start">Getting Started</a>写的也比较含糊，所以如何使用这个工具反而成为第一道门槛，尤其对于那些对Python不熟悉的同学来说。所以，下面的重点是介绍如何在Windows上使用YUI Doc：<span id="more-1418"></span></p>
<ol>
<li>下载<a href="http://www.python.org/ftp/python/2.5.2/python-2.5.2.msi">Python2.5.2</a>安装之。<br />
虽然Python3.0和Python2.6都已经出来很久了，但之所以依旧选择Python2.5.2，是因为后面要用到的安装Python扩展库的工具<a href="http://pypi.python.org/pypi/setuptools#credits">setuptools</a>在Windows下的最新版本对应的是Python2.5。我不知道它是否支持2.5以上，有兴趣的可以试试。
</li>
<li>下载<a href="http://pypi.python.org/packages/2.5/s/setuptools/setuptools-0.6c9.win32-py2.5.exe#md5=602d06054ec1165e995ae54ac30884d7">setuptools-0.6c9.win32-py2.5.exe</a>并安装之，setuptools会自动安装到Python所在安装目录的Scripts目录下。<br />
<a href="http://peak.telecommunity.com/DevCenter/setuptools">setuptools</a>为Python提供了简单的包管理和发行功能。后面的扩展库的安装就是利用它的easy_install，非常方便。有兴趣的可以看看<a href="http://www.ibm.com/developerworks/cn/linux/l-cppeak3.html">《可爱的 Python: 使用 setuptools 孵化 Python egg》</a>。</li>
<li>为了使用方便需要配置一下“环境变量”，即在“我的电脑 》右键 》属性 》高级 》环境变量 》系统变量 》 选中Path 》 编辑”，在弹出框中加入：
<pre><code>;D:\Program Files\python;D:\Program Files\python\Scripts</code></pre>
<p>然后应用即可。前面的两个路径分别是我的Python和setuptools的安装路径，你需要修改成你自己的。
</li>
<li>开始 》运行 》(Win + R)输入“cmd”，输入：
<pre><code>python -c "import pkg_resources"</code></pre>
<p>没有任何输出，即表示setuptools安装成功。接着依次输入运行：</p>
<pre><code>easy_install Pygments
easy_install simplejson
easy_install Cheetah
</code></pre>
<p>setuptools会自动寻找并下载<a href="http://pygments.org/">Pygments</a>、<a href="http://svn.red-bean.com/bob/simplejson/tags/simplejson-1.3/docs/index.html">SimpleJSON</a>和<a href="http://www.cheetahtemplate.org/">Cheetah</a>这三个扩展库，并安装它。
</li>
<li>下载最新版本<a href="http://github.com/yui/yuidoc/downloads">YUI Doc</a>，并解压在某个目录下。复制其bin目录下的example.bat文件，重命名为test.bat，然后用记事本或其他编辑器打开并配置它:
<pre><code>SET yuidoc_home="D:\yui\yuidoc"
<span>REM YUI Doc的路径</span>
SET parser_in="D:\yui\src"
<span>REM 要生成文档的JS文件路径，比如为了测试就我临时建一个，里面就放着YUI 的 dom.js</span>
SET parser_out="D:\yui\src\parser"
<span>REM YUI Doc会把解析的JS文件提取出来所要存放的位置</span>
SET generator_out="D:\yui\src\generator"
<span>REM 生成文档存放的位置</span>
</code></pre>
<p>保存并运行test.bat后，就会发现D:\yui\src中多了parser和generator两个目录，而generator中正是你要的文档。
</li>
</ol>
<h3>支持中文注释的解决方案</h3>
<ol>
<li>下载最新版本<a href="http://github.com/yui/yuidoc/downloads">YUI Doc</a>，解决方案在<a href="http://github.com/yui/yuidoc/zipball/yuidoc-27">yuidoc-27</a>中验证通过</li>
<li>把所有.js文件都转成不带BOM的UTF-8编码</li>
<li>修改文件/bin/yuidoc_highlight.py：
<pre><code>from pygments.formatters import HtmlFormatter
<span>#新增下行</span>
import codecs
<span>...</span>
<span>#f=open(os.path.join(path, file))</span>
</span>#fileStr=StringIO(f.read()).getvalue()</span>
</span>#f.close()</span>
fileStr = codecs.open( os.path.join(path, file), "r", "utf-8" ).read()
log.info("highlighting " + file)

<span>#highlighted = highlightString(fileStr)</span>
highlighted = highlightString(unicode(fileStr))
</code></pre>
</li>
<li>在Python的\Lib\site-packages\下增加一个名为sitecustomize.py的文件，其内容为：
<pre><code>import sys
sys.setdefaultencoding('utf-8')
</code></pre>
</li>
</ol>
<p>谢谢小马提供中文注释的解决方案</p>
<p>学会使用工具仅仅是开始了一小步，仔细看看<a href="http://developer.yahoo.com/yui/yuidoc/#overview">YUI Doc的官方文档</a>吧，利用其来促使我们写出更高效优雅的前端代码并惠及更多的人才是一大步。</p>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2008/12/30/why-start-yui-doc/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>连续字符自动换行的解决方案</title>
		<link>http://dancewithnet.com/2008/12/04/word-break-all/</link>
		<comments>http://dancewithnet.com/2008/12/04/word-break-all/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 16:16:50 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[HTML & CSS]]></category>
		<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[break-all]]></category>
		<category><![CDATA[break-word]]></category>
		<category><![CDATA[createTreeWalker]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[word-break]]></category>
		<category><![CDATA[word-wrap]]></category>
		<category><![CDATA[跨浏览器]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1386</guid>
		<description><![CDATA[文本的排版依据语言的不同会有一些格式上的要求，比如简体中文中类似逗号、分号等标点符号不会出现在一行的开头，对于英文来讲就是一个完整单词不会在两行显示，浏览器会依据类似这... ]]></description>
			<content:encoded><![CDATA[<p>文本的排版依据语言的不同会有一些格式上的要求，比如简体中文中类似逗号、分号等标点符号不会出现在一行的开头，对于英文来讲就是一个完整单词不会在两行显示，浏览器会依据类似这样的原则来显示文本。但是由于网页有宽度限制的，连续的超长的字母、数字或标点符号超出其所在区域宽度的限制而导致影响页面视觉，如<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo1">例1</a>所示。这个问题在显示用户输入信息时尤为突出，这里就是要说如何解决这个问题。</p>
<p>在<a href="http://www.w3.org/TR/css3-text/">CSS3草案</a>中，对文本的处理新增了两个新属性<a href="http://www.w3.org/TR/css3-text/#word-wrap">word-wrap</a>和<a href="http://www.w3.org/TR/css3-text/#word-break">word-break</a>来解决这个问题：</p>
<ol>
<li>{word-break:break-all;} ：依照亚洲语言和非亚洲语言的文本规则，允许在字内换行，且允许非亚洲语言文本行的任意字内断开</li>
<li> {word-wrap:break-word;}： 内容将在边界内换行，如需要则词内换行（word-break）也行发生</li>
</ol>
<p><span id="more-1386"></span></p>
<p>下面是常见浏览器的支持情况：</p>
<table>
<tbody>
<tr>
<th></th>
<th>IE6/7/8<sup>[1]</sup></th>
<th>Firefox2/3<sup>[2]</sup></th>
<th>Firefox3.5</th>
<th>Opera9+</th>
<th>Safari9.5+/Chrome</th>
</tr>
<tr>
<th>{word-wrap:break-word;}</th>
<td>td元素需设置其宽度<br />见<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo4">例4</a>和<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo5">例5</a></td>
<td>不支持</td>
<td>不支持td元素<br />见<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo4">例4</a>和<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo5">例5</a></td>
<td>不支持</td>
<td>不支持td元素<br />见<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo4">例4</a>和<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo5">例5</a></td>
</tr>
<tr>
<th>{word-break:break-all;}</th>
<td>不支持连续的符号<br />见<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo3">例3</a></td>
<td>不支持</td>
<td>不支持连续的符号<br />见<a href="http://dancewithnet.com/lab/2008/word-break-all/#demo3">例3</a></td>
<td>不支持</td>
<td>支持</td>
</tr>
</tbody>
</table>
<ul class="refer">
<li>[1] <del datetime="2009-05-13T17:07:03+08:00">在MSDN的<a href="http://msdn.microsoft.com/en-us/library/cc351024(VS.85).aspx#font">CSS Compatibility and Internet Explorer</a>中可以看出，IE8会像IE6和IE7一样支持word-wrap和word-break这两个属性，但我在IE8beta2上测试来看却不支持这两项，由于IE8还处于beta阶段，且我相信IE8最终会支持的，所以在页头声明<code>&lt;meta content="IE=7" http-equiv="X-UA-Compatible" /&gt;</code>使IE8按照IE7来解释页面是一个不错的办法。</del><ins datetime="2009-05-13T21:08:52+08:00"><a href="http://msdn.microsoft.com/en-us/library/ms531186.aspx">IE8正式版支持</a></ins></li>
<li>[2] <del datetime="2009-05-13T17:07:03+08:00">Firefox3.1将会支持word-wrap属性</del><ins datetime="2009-05-13T17:07:03+08:00">Firefox3.5beta4已经支持</ins></li>
</ul>
<p>由于{word-break:break-all;}导致英文和数字可读性严重下降且无法使连续符号换行，所以{word-wrap:break-word;}是一个相对较好的选择。需要注意的是各个浏览器中word-wrap在td上实现不一致，所以避免直接在td上使用。</p>
<p>但面对浏览器的如此糟糕支持，所以不能不借助JavaScript来解决这个问题，即当浏览器不支持CSS解决方案时，在连续字符串的适当位置插入&amp;#8203;字符（当然还可以用<code>&lt;wbr /&gt;</code>和&amp;shy;，这三个字符在浏览器中的支持情况请看<a href="http://www.quirksmode.org/oddsandends/wbr.html">ppk的《The wbr tag》</a>），这些字符写在浏览器中不会显示，却使长字符串换行。<ins datetime="2009-05-30T15:47:29+08:00">&amp;#8203;和&amp;shy;都会导致复制用其处理过的文本时有大量不可打印的字符，导致字符数急剧增大，更严重的是导致复制的链接字符串不可用，所以用<code>&lt;wbr /&gt;</code>是比较好的方案，虽然<code>&lt;wbr /&gt;</code>在IE8中不被支持且在Safari中有bug，但这些浏览器可以直接用CSS{word-wrap:break-word}来实现无需用<code>&lt;wbr /&gt;</code>处理。</ins><ins datetime="2009-06-04T22:46:16+08:00">Opera下要兼容<code>&lt;wbr /&gt;</code>，需要设置CSS：<code>wbr:after { content: "\00200B" }</code></ins>。
</p>
<p><ins datetime="2009-05-28T18:02:06+08:00">2009.05.28重写了实现方法，尽可能减少对浏览器探测的依赖，同时考虑对同一个页面多次执行该方法的效率，同时为了偷懒直接基于YUI。<a href="http://dancewithnet.com/lab/2008/word-break-all/break-word-req-yui.html" class="link-btn">请看DEMO</a></ins></p>
<p>具体实现代码如下：</p>
<pre><code>function fnBreakWordAll(o){
var o = o || {},
  iWord = o.word || 13,
  iRe = o.re || '[a-zA-Z0-9]',
  bAll = o.all || false,
  sClassName = o.className || 'word-break-all',
  aEls = o.els || (function(){
    var aEls = [],
      aAllEls = document.getElementsByTagName('*'),
      re = new RegExp('(?:^|\\s+)' + sClassName + '(?:\\s+|$)');
    for(var i =0,iLen = aAllEls.length; i &lt; iLen ; ++i){
      if(re.test(aAllEls[i].className)){
        aEls[aEls.length] = aAllEls[i];
      }
    }
    return aEls;
  })() || [],
  fnBreakWord = function(oEl){
    <span>// 基于http://www.hedgerwow.com/360/dhtml/css-word-break.html修改</span>
    if(!oEl || oEl.nodeType !== 1){
      return false;
    }else if(oEl.currentStyle &#038;&#038; typeof oEl.currentStyle.wordWrap==='string'){
      breakWord = function(oEl){
        oEl.runtimeStyle.wordWrap = 'break-word';
        return true;
      }
      return breakWord(oEl);
    }else if(document.createTreeWalker){
      var trim = function  (str) {
        str = str.replace(/^\s\s*/, '');
        var ws = /\s/,
        i = str.length;
        while (ws.test(str.charAt(--i)));
        return str.slice(0, i + 1);
      }
      breakWord = function(oEl){
        var dWalker=document.createTreeWalker(oEl,NodeFilter.SHOW_TEXT,null,false);
        var node,s,c = String.fromCharCode('8203'),
          <span>//re = /([a-zA-Z0-9]{0,13})/;</span>
          re = new RegExp('('+ iRe +'{0,' + iWord + '})');
        while (dWalker.nextNode()){
          node = dWalker.currentNode;
          s = trim(node.nodeValue).split(re).join(c);
          node.nodeValue = s;
        }
        return true;
      }
      return breakWord(oEl);
    }
  };
for(var i=0,n=aEls.length; i&lt;n; ++i){
  var sUa = navigator.userAgent,
    sTn = aEls[i].tagName.toLowerCase() ;
  if((/Opera/).test(sUa) || (/Firefox/).test(sUa) || ((/KHTML/).test(sUa) &#038;&#038;
  (sTn === 'td' || sTn === 'th')) || bAll){
    fnBreakWord(aEls[i]);
  }
}
}</code></pre>
<p>具体应用请看<a href="http://dancewithnet.com/lab/2008/word-break-all/kill-all.html" class="link-btn">演示实例</a></p>
<p>fnWordBreakAll函数提供一些定制参数，使用方法和参数含义如下：</p>
<pre><code>fnWordBreakAll({word:15,re:'[\\w]',all:true});</code></pre>
<table>
<tr>
<th>参数</th>
<th>值</th>
<th>说明</th>
</tr>
<tr>
<th>word</th>
<td>正整数，默认是13</td>
<td>在这个字数内的单词不会被插入\u8203，印象中超过13个字母的单词不多，这可以保证绝大部分单词不会被打碎</td>
</tr>
<tr>
<th>re</th>
<td>正则表达式，默认[a-zA-Z0-9]</td>
<td>单词的正则表达式，用以确定一个单词是哪些字符组成，注意\的转义</td>
</tr>
<tr>
<th>all</th>
<td>布尔值，默认false</td>
<td>确定是否在所有的浏览器中执行，默认在Opera和Firefox，以及当class应用在th或td的Safari上执行，这个主要用在.word-break-all没有定义时，会对IE加上样式</td>
</tr>
<tr>
<th>className</th>
<td>合法class名，默认word-break-all</td>
<td>执行函数的元素对应属性名</td>
</tr>
</table>
<p>这个函数的核心部分修改自Hedger Wang 整理了一个JavaScript解决方案<a href="http://www.hedgerwow.com/360/dhtml/css-word-break.html">《Cross Browser Word Breaker》</a>，其利用<a href="https://developer.mozilla.org/En/DOM/Document.createTreeWalker">document.createTreeWalker</a>和split方法给非IE浏览器的每个字符间加入了&amp;#8203;，它用在纯中文文本基本上没有什么问题，但是如果你仔细观察他给出的例子就会发现文本中有英文或数字时，虽然解决了换行问题，但是使文本难以阅读，且增大了字符间的间距，所以我在此基础上做了上面的改进。</p>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2008/12/04/word-break-all/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>JavaScript的陷阱</title>
		<link>http://dancewithnet.com/2008/10/27/javascript-gotchas/</link>
		<comments>http://dancewithnet.com/2008/10/27/javascript-gotchas/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 16:26:23 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[for]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[null]]></category>
		<category><![CDATA[parseInt]]></category>
		<category><![CDATA[String.replace()]]></category>
		<category><![CDATA[switch]]></category>
		<category><![CDATA[this]]></category>
		<category><![CDATA[undefined]]></category>
		<category><![CDATA[匿名函数]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/?p=1366</guid>
		<description><![CDATA[这本来是翻译Estelle Weyl的《15 JavaScript Gotchas》，里面介绍的都是在JavaScript编程实践中平时容易出错或需要注意的地方，并提供避开这些陷阱的方法，总体上讲，就是在认清事物本质的基础样要... ]]></description>
			<content:encoded><![CDATA[<p>这本来是翻译Estelle Weyl的<a href="http://www.evotech.net/blog/2008/10/13-javascript-gotchas/">《15 JavaScript Gotchas》</a>，里面介绍的都是在JavaScript编程实践中平时容易出错或需要注意的地方，并提供避开这些陷阱的方法，总体上讲，就是在认清事物本质的基础样要坚持好的编程习惯，其实这就是Douglas Crockford很久以前提出的JavaScript风格要素问题了，有些内容直接是相同的，具体请看<a href="http://dancewithnet.com/2008/01/26/the-elements-of-javascript-style-part-one/">《Javascript风格要素（1）》</a>和<a href="http://dancewithnet.com/2008/01/30/the-elements-of-javascript-style-part-two/">《Javascript风格要素（2）》</a>。在翻译的过程中，我又看到了贤安去年翻译的<a href="http://realazy.org/blog/2007/08/20/nine-javascript-gotchas/">《JavaScript的9个陷阱及评点》</a>，其内容又有些交叉在一起，所以我就在现有翻译的基础上做了一个简单的拼合，并依据自己的理解增加了一些注释和解释。<span id="more-1366"></span></p>
<ol>
<li><a href="#case-sensitivity">区分大小写：变量名、属性和方法全部都区分大小写</a></li>
<li><a href="#mismatching">不匹配的引号、圆括号或花括号将抛出错误</a></li>
<li><a href="#conditional-statements">条件语句：3个常见陷阱</a></li>
<li><a href="#line-breaks">换行：一直用分号结束语句来避免常见的换行问题</a></li>
<li><a href="#punctuation">标点法：在对象声明的尾部逗号将导致出错</a></li>
<li><a href="#html-id-conflicts">HTML id 冲突</a></li>
<li><a href="#variable-scope">变量作用域：全局变量对局部变量</a></li>
<li><a href="#function-overloading">函数重载：当重载不存在时，覆盖函数</a></li>
<li><a href="#string-replace">区分string.replace()函数不是全局的</a></li>
<li><a href="#parseInt">parseInt应该包含两个参数</a></li>
<li><a href="#this">“this”和绑定问题</a></li>
<li><a href="#default-param-value">为参数设置默认值，以免你遗漏它们</a></li>
<li><a href="#for-statements">for each循环是用于对象而不是数组</a></li>
<li><a href="#switch-statements">switch语句需要点技巧</a></li>
<li><a href="#undefined-vs-null">如果你要检查null，应该先检查undefined</a></li>
<li><a href="#event-handlers">时间处理陷阱</a></li>
</ol>
<h3 id="case-sensitivity">区分大小写</h3>
<p>变量名和函数名都是区分大小写的。就像配错的引号一样，这些大家都知道。但是，由于错误是不作声的，所以这是一个提醒。为自己选择一个命名规则，并坚持它。而且，记住JavaScript中的原生函数和CSS属性都是<a href="http://zh.wikipedia.org/wiki/驼峰式大小写">骆驼拼写法（camelCase）</a>。</p>
<pre><code>getElementBy<strong>Id</strong>(’myId’) != getElementBy<strong>ID</strong>(’myId’); <span>//它应该是“Id”而不是“ID”</span>
getElementById(’my<strong>Id</strong>‘) != getElementById(’my<strong>ID</strong>‘); <span>// “Id”也不等于“ID”</span>

document.getElementById('myId').style.<strong>Color</strong>; <span>//返回 "undefined"</span>
</code></pre>
<h3 id="mismatching">不匹配的引号、圆括号或花括号</h3>
<p>避免陷入不匹配的引号、圆括号或花括号陷阱的最好方式是编码时一直同时写出打开和关闭这两个元素符号，然后在其中间加入代码。开始：</p>
<pre><code>var myString = ""; <span>//在输入字符串值之前写入这对引号</span>
function myFunction(){
 if(){<span>//关闭每个打开的括弧</span>
 }
}
<span>//统计所有的左括号和右括号数量，并且确保它们相等</span>
alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); <span>//关闭每个打开的圆括号</span>
</code></pre>
<p>每当你打开一个元素，请关闭它。当你添加了关闭圆括号后，你再把函数的参数放进圆括号中。如果有一串圆括号，统计所有打开的圆括号和所有关闭的圆括号，并且确保这两个数字相等。</p>
<h3 id="conditional-statments">条件语句（3个陷阱）</h3>
<ol>
<li>所有的条件语句都必须位于圆括号中。<ins datetime="2008-10-28T18:05:25+80:00">执行语句主体不管是一句还是多句都强烈建议用花括号包围起来，这样能避免很多因修改或嵌套而产生的潜在错误。</ins>
<pre><code>if(var1 == var2){<span>//statement</span>}</code></pre>
</li>
<li>不要犯无意地使用赋值运算符的错误：把第二个参数的值赋给第一个参数。因为它是一个逻辑问题，它将一直返回true且不会报错。
<pre><code>if(var1 = var2){} <span>// 返回true。把var2赋值给var1</span></code></pre>
</li>
<li>JavaScript是弱类型，除了在<a href="http://www.evotech.net/blog/2007/07/javascript-switch-statement-quirks/">switch语句</a>中。当JavaScript在case比较时，它是非弱类型。
<pre><code>var myVar = 5;
if(myVar == '5'){ <span>//返回true，因为JavaScript是弱类型</span>
 alert("hi");  <span>//这个alert将执行，因为JavaScript通常不在意数据类型</span>
}
switch(myVar){
 case '5':
 alert("hi"); <span>//这个alert将不会执行，因为数据类型不匹配</span>
}
</code></pre>
</li>
</ol>
<h3 id="line-breaks">换行</h3>
<p>当心JavaScript中的硬换行。换行被解释为表示行结束的分号。即使在字符串中，如果在引号中包括了一个硬换行，那么你会得到一个解析错误（未结束的字符串）。</p>
<pre><code>var bad  = '&lt;ul id="myId"&gt;
  &lt;li&gt;some text&lt;/li&gt;
  &lt;li&gt;more text&lt;/li&gt;
  &lt;/ul&gt;'; <span>// 未结束的字符串错误</span>

var good = '&lt;ul id="myId"&gt;' +
 ‘&lt;li&gt;some text&lt;/li&gt;‘ +
 ‘&lt;li&gt;more text&lt;/li&gt;‘ +
 ‘&lt;/ul&gt;’; <span>// 正确</span>
</code></pre>
<p>前面讨论过的换行被解释为分号的规则并不适用于控制结构这种情况：条件语句关闭圆括号后的换行并不是给其一个分号。</p>
<p>一直使用分号和圆括号，那么你不会因换行而出错，你的代码易于阅读，且除了那些不使用分号的怪异源码外你会少一些顾虑：所以当移动代码且最终导致两个语句在一行时，你无需担心第一个语句是否正确结束。</p>
<h3 id="punctuation">多余的逗号</h3>
<p>在任何JavaScript对象定义中，最后一个属性决不能以一个逗号结尾。Firefox不会出错，而IE会报语法错误。</p>
<pre><code>var theObj = {
        city : "Boston",
        state : "MA",<span>//IE6和IE7中有“缺少标识符、字符串或数字”的错误，IE8 beta2修正了它</span>
  }</code></pre>
<h3 id="html-id-conflicts">HTML id 冲突</h3>
<p><a href="http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html">JavaScript DOM绑定（JavaScript DOM bindings）</a>允许通过HTML id索引。在JavaScript中函数和属性共享同一个名字空间。所以，当在HTML中的一个id和函数或属性有相同的名字时，你会得到难以跟踪的逻辑错误。然而这更多是一个<a href="http://www.evotech.net/blog/2007/04/css-best-practices/">CSS最佳实践</a>的问题，当你不能解决你的JavaScript问题时，想起它是很重要的。</p>
<pre><code>
&lt;ul&gt;
&lt;li id="length"&gt;1&lt;/li&gt;
&lt;li id="thisLength"&gt;2&lt;/li&gt;
&lt;li id="thatLength"&gt;3&lt;/li&gt;
&lt;/ul&gt;
&lt;script&gt;
var listitems = document.getElementsByTagName('li');
var liCount = listitems.length; <span>//IE下返回的是&lt;li id="length"&gt;1&lt;/li&gt;这个节点而不是所有&lt;li的数量</span>

var thisLength = document.getElementById('thisLength');
    thatLength = document.getElementById('thatLength');
    <span>//IE下会出现“对象不支持此属性和方法”的错误，IE8 beta2下首次加载页面会出错，刷新页面则不会</span>
    <span>//在IE中thisLength和thatLength直接表示以其为id值的DOM节点，</span>
    <span>//所以赋值时会出错，当有var声明时，IE会把其当着变量，这个时候就正常了。</span>
&lt;/script&gt;
</code></pre>
<p> 如果你要标记(X)HTML，绝不要使用JavaScript方法或属性名作为id的值。并且，当你写JavaScript时，避免使用 (X)HTML中的id值作为变量名。</p>
<h3 id="variable-scope">变量作用域</h3>
<p>JavaScript中的许多问题都来自于变量作用域：要么认为局部变量是全局的，要么用函数中的局部变量覆盖了全局变量。为了避免这些问题，最佳方案是根本没有任何全局变量。但是，如果你有一堆，那么你应该知道这些陷阱。</p>
<p>不用var关键字声明的变量是全局的。记住使用var关键字声明变量，防止变量具有全局作用域。在下面例子中，在函数中声明的变量具有全局变量，因为没有使用var关键字声明：</p>
<pre><code>anonymousFuntion1 = function(){
 globalvar = 'global scope'; <span>//全局声明，因为“var”遗漏了</span>
 return localvar;
}();
alert(globalvar); <span>//弹出“global scope”，因为函数中的变量是全局声明</span>

anonymousFuntion2 = function(){
 var localvar = 'local scope'; <span>//使用“var”局部声明</span>
 return localvar;
}();
alert(localvar); <span>//错误 “localvar未定义”。没有全局定义localvar</span>
</code></pre>
<p>作为参数引进到函数的变量名是局部的。如果参数名也是一个全局变量的名字，像参数变量一样有局部作用域，这没有冲突。如果你想在函数中改变一个全局变量，这个函数有一个参数复制于这个全局变量名，记住所有全局变脸都是window对象的属性。</p>
<pre><code>var myscope = "global";
function showScope(myscope){
 return myscope; <span>//局部作用域，即使有一个相同名字的全局变量</span>
}
alert(showScope('local'));

function globalScope(myscope){
 myscope = <strong>window.myscope</strong>; <span>//全局作用域</span>
 return myscope;
}
alert(globalScope(’local’));
</code></pre>
<p>你甚至可以在循环中声明变量：</p>
<pre><code>for(var i = 0; i < myarray.length; i++){}</code></code></pre>
<h3 id="function-overloading">覆盖函数/重载函数</h3>
<p>当你不止一次的声明一个函数时，这个函数的最后一次声明将覆盖掉该函数的所有前面版本且不会抛出任何错误或警告。这不同于其他的编程语言，像Java，你能用相同的名字有多重函数，只要它们有不同的参数：调用函数重载。在JavaScript中没有重载。这使得不能在代码中使用JavaScript核心部分的名字极其重要。也要当心包含的多个JavaScript文件，像一个包含的脚本文件可能覆盖另一个脚本文件中的函数。请使用匿名函数和名字空间。</p>
<pre><code>(function(){
 <span>// creation of my namespace 创建我的名字空间</span>
 if(!window.MYNAMESPACE) {
  window['MYNAMESPACE'] = {};
 }
 <span>//如果名字空间不存在，就创建它</span>
 <span>//这个函数仅能在匿名函数中访问</span>
 function myFunction(var1, var2){
  <span>//内部的函数代码在这儿</span>
 }
 <span>// 把内部函数连接到名字空间上，使它通过使用名字空间能访问匿名函数的外面 </span>
 window['MYNAMESPACE']['myFunction'] = myFunction;
})(); <span>// 圆括号 = 立即执行</span>
<span>// 包含所有代码的圆括号使函数匿名</span>
</code></pre>
<p>这个例子正式为了实现解决上一个陷阱“变量作用域”的最佳方案。匿名函数详细内容请看<a href="http://dancewithnet.com/2008/05/07/javascript-anonymous-function/">《Javascript的匿名函数》</a>。<a href="http://developer.yahoo.com/yui/">YUI</a>整个库只有YAHOO和YAHOO_config两个全局变量，它正是大量应用匿名函数和命名空间的方法来实现，具体请看<a href="http://dancewithnet.com/2007/12/04/a-javascript-module-pattern/">《Javascript的一种模块模式》</a>。</p>
<h3 id="string-replace">字符串替换</h3>
<p>一个常见错误是假设字符串替换方法的行为会对所有可能匹配都产生影响。实际上，JavaScript字符串替换只改变了第一次发生的地方。为了替换所有发生的地方，你需要设置全局标识。同时需要记住String.replace()的第一个参数是一个正则表达式。</p>
<pre><code>var myString = "this is my string";
myString = myString.replace("","%20"); // "this%20is my string"
myString = myString.replace(/ /,"%20"); // "this%20is my string"
myString = myString.replace(/ /g,"%20"); // "this%20is%20my%20string"
</code></pre>
<h3 id="parseInt">parseInt</h3>
<p>在JavaScript得到整数的最常见错误是假设parseInt返回的整数是基于10进制的。别忘记第二个参数基数，它能是从2到36之间的任何值。为了确保你不会弄错，请一直包含第二个参数。</p>
<pre><code>parseInt('09/10/08'); <span>//0</span>
parseInt(’09/10/08′,10); <span>//9, 它最可能是你想从一个日期中得到的值</span>
</code></pre>
<p>如果parseInt没有提供第二个参数，则前缀为 &#8216;0x&#8217; 的字符串被当作十六进制，前缀为 &#8216;0&#8242; 的字符串被当作八进制。所有其它字符串都被当作是十进制的。如果 numString 的前缀不能解释为整数，则返回 NaN（而不是数字）。</p>
<h3 id="this">‘this’</h3>
<p>另一个常见的错误是忘记使用“this”。在JavaScript对象中定义的函数访问这个对象的属性，但没有使用引用标识符“this”。例如，下面是错误的：</p>
<pre><code>function myFunction() {
 var myObject = {
  objProperty: "some text",
  objMethod: function() {
   alert(objProperty);
  }
 };
 myObject.objMethod();
} 

function myFunction() {
 var myObject = {
  objProperty: "some text",
  objMethod: function() {
   alert(this.objProperty);
  }
 };
 myObject.objMethod();
}
</code></pre>
<p>有一篇<a href="http://www.alistapart.com/articles/getoutbindingsituations">A List Apart文章</a>用通俗易懂的英文表达了this绑定的问题。</p>
<p>对this使用最大的陷阱是this在使用过程中其引用会发生改变：</p>
<pre><code>&lt;input type="button" value="Gotcha!" id="MyButton"&gt;
&lt;script&gt;
var MyObject = function () {
    this.alertMessage = "Javascript rules";
    this.ClickHandler = function() {
        <strong>alert(this.alertMessage );</strong>
        <span>//返回结果不是”JavaScript rules”，执行MyObject.ClickHandler时，</span>
        <span>//this的引用实际上指向的是document.getElementById("theText")的引用</span>
  }
}();
document.getElementById(”theText”).onclick =  MyObject.ClickHandler
&lt;/script&gt;
</code></pre>
<p>其解决方案是：</p>
<pre><code>
var MyObject = function () {
    <strong>var self = this;</strong>
    this.alertMessage = “Javascript rules”;
    this.OnClick = function() {
        alert(self.value);
    }
}();
</code></pre>
<p>类似问题的更多细节和解决方案请看<a href="http://realazy.org/blog/2007/07/18/scope-in-javascript/">《JavaScript作用域的问题》</a>。</p>
<h3 id="default-param-value">遗漏的参数</h3>
<p>当给函数增加一个参数时，一个常见的错误是忘记更新这个函数的所有调用。如果你需要在已经被调用的函数中增加一个参数来处理一个特殊情况下的调用，请给这个函数中的这个参数设置默认值，以防万一在众多脚本中的众多调用中的一个忘记更新。</p>
<pre><code>function addressFunction(address, city, state, country){
 <strong>country = country || “US”</strong>; <span>//如果没有传入country,假设 “US”</span>
 span>//剩下代码
}
</code></pre>
<p>你也能通过获取arguments来解决。但是在这篇文章我们的注意力在陷阱上。同时在<a href="http://dancewithnet.com/2008/01/30/the-elements-of-javascript-style-part-two/">《Javascript风格要素（2）》</a>也介绍了||巧妙应用。</p>
<h3 id="for-statements">for关键字</h3>
<p>在JavaScript中关键字for有两种使用方式，一个是for语句，一个是for/in语句。for/in语句将遍历所有的对象属性（attribute），包括方法和属性（property）。决不能使用for/in来遍历数组：仅在当需要遍历对象属性和方法时才使用for/in。</p>
<ol>
<li>for(var myVar in myObject)语句用一个指定变量无任何规律地遍历对象的所有属性。如果for/in循环的主体删除了一个还没有枚举出的属性，那么该属性就不在枚举。如果循环主体定义了新属性，那么循环是否枚举该属性则是由JavaScript的实现决定。</li>
<li>for(var 1=0; i < myArray.length; i++)语句会遍历完一个数组的所有元素。</li>
</li>
</ol>
<p>为了解决这个问题，大体上你可以对对象使用 for &#8230; in，对数组使用for循环：</p>
<pre><code>listItems = document.getElementsByTagName('li');
for (var listitem in listItems){
 <span>//这里将遍历这个对象的所有属性和方法，包括原生的方法和属性，但不遍历这个数组：出错了！</span>
}
<span>//因为你要循环的是数组对象，所用for循环</span>
for ( var i = 0; i < listItems.length; i++) {
 <span>//这是真正你想要的
}
</code></pre>
<p>对象的有些属性以相同的方式标记成只读的、永久的或不可列举的，这些属性for/in无法枚举。实际上，for/in循环<br />
会遍历所有对象的所有可能属性，包括函数和原型中的属性。所有修改原型属性可能对for/in循环带来致命的危害，所以需要采用hasOwnProperty和typeof做一些必要的过滤，最好是用for来代替for/in。</p>
<h3 id="switch-statements">switch语句</h3>
<p>Estelle Weyl写了一篇<a href="http://www.evotech.net/blog/2007/07/javascript-switch-statement-quirks/">switch statement quirks</a>，其要点是：</p>
<ol>
<li>没有数据类型转换</li>
<li>一个匹配，所有的表达式都将执行直到后面的break或return语句执行</li>
<li>你可以对一个单独语句块使用多个case从句</li>
</ol>
<h3 id="undefined-vs-null">undefined ≠ null</h3>
<p>null是一个对象，undefined是一个属性、方法或变量。存在null是因为对象被定义。如果对象没有被定义，而测试它是否是null，但因为没有被定义，它无法测试到，而且会抛出错误。</p>
<pre><code>if(myObject !== null  &#038;&#038; typeof(myObject) !== 'undefined') {
 <span>//如果myObject是undefined，它不能测试是否为null，而且还会抛出错误</span>
}
if(typeof(myObject) !== 'undefined' &#038;&#038; myObject !== null) {
 <span>//处理myObject的代码</span>
}
</code></pre>
<p><a href="http://blog.poundbang.in/post/30056940/javascript-gotcha-undefined-vs-null">Harish Mallipeddi</a>对undefined和null有一个说明。</p>
<h3 id="event-handlers">事件处理陷阱</h3>
<p>刚接触事件处理时最常见的写法就是类似：</p>
<pre><code>window.onclick = MyOnClickMethod</code></pre>
<p>这种做法不仅非常容易出现后面的window.onclick事件覆盖掉前面的事件，还可能导致大名顶顶的IE内存泄露问题。为了解决类似问题，4年前<a href="http://simon.incutio.com/archive/2004/05/26/addLoadEvent">Simon Willison</a>就写出了很流行的addLoadEvent()：</p>
<pre><code>function addLoadEvent(func) {
 var oldonload = window.onload;
 if (typeof window.onload != 'function') {
  window.onload = func;
 }else {
  window.onload = function() {
   oldonload();
   unc();
  }
 }
}
addEvent(window,'load',func1,false);
addEvent(window,'load',func2,false);
addEvent(window,'load',func3,false);
</code></pre>
<p>当然在JavaScript库盛行的现在，使用封装好的事件处理机制是一个很好的选择，比如在YUI中就可以这样写：</p>
<pre><code>YAHOO.util.Event.addListener(window, "click", MyOnClickMethod);</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2008/10/27/javascript-gotchas/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>

