<?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>welefen &#187; 前端开发</title>
	<atom:link href="http://www.welefen.com/category/js-css-html/feed" rel="self" type="application/rss+xml" />
	<link>http://www.welefen.com</link>
	<description>风为人世在，在世人为风。</description>
	<lastBuildDate>Thu, 09 Sep 2010 11:29:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>如何减少代码上线过程中对线上服务的影响</title>
		<link>http://www.welefen.com/reduce-bad-online-service-on-upgrade.html</link>
		<comments>http://www.welefen.com/reduce-bad-online-service-on-upgrade.html#comments</comments>
		<pubDate>Thu, 09 Sep 2010 11:29:24 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[互联网]]></category>
		<category><![CDATA[前端开发]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=362</guid>
		<description><![CDATA[目前现状 在一些大公司中，每个服务几乎都有CDN，也就是说一个服务都有很多很多的服务器。并且一般做服务优化的话往往是把程序和静态资源放在不同的服务器上。 在实际开发中，一般是按功能将代码分成不同的模块。上线时OP一般是一个模块一个模块的上线。虽然上线时是并行上线的，但每个模块以及模板与静态资源生效是有时间差的。尤其是模块之间依赖程度很高，如：模板和静态资源依赖程度很高，上线有时间差极有可能出现JS报错或者一些点击不能响应。 所以在上线这个时间差内，用户在操作过程中极有可能出现问题。 解决方案 改变已有的一个模块一个模块的上线方案，而是先将所有要上线的文件都传到各个机器上去，并不是直接覆盖线上文件，而是通过一个的规则成为新建的文件。 如：我要上线覆盖的文件夹为 vote，那么先将代码都拷贝到vote.online文件下（各个机器），其他模块的代码拷贝到其他对应的文件夹下。待所有要上线的代码都准备好后，然后执行mv的操作，将要上线的代码覆盖到真正的文件夹下。在这个过程中，虽然要有时长，但这个时间要小很多。 借助自动化上线，这种方式要比现有的上线要快很多。上线时间差越小，对线上服务的影响越小。 特殊情况 上面讲的方式虽然将时间差缩小了很多，但还是有一些很小的时间差。对于一般的服务大家都是可以接受的，但对于一些交易类的服务（如：电子商务，金融），这种时间差还是不能接受的。对于这种要求非常严格的服务估计还是只能夜里停服务上线了。]]></description>
			<content:encoded><![CDATA[<h2>目前现状</h2>
<p>在一些大公司中，每个服务几乎都有CDN，也就是说一个服务都有很多很多的服务器。并且一般做服务优化的话往往是把程序和静态资源放在不同的服务器上。</p>
<p>在实际开发中，一般是按功能将代码分成不同的模块。上线时OP一般是一个模块一个模块的上线。虽然上线时是并行上线的，但每个模块以及模板与静态资源生效是有时间差的。尤其是模块之间依赖程度很高，如：模板和静态资源依赖程度很高，上线有时间差极有可能出现JS报错或者一些点击不能响应。 所以在上线这个时间差内，用户在操作过程中极有可能出现问题。</p>
<h2>解决方案</h2>
<p>改变已有的一个模块一个模块的上线方案，而是先将所有要上线的文件都传到各个机器上去，并不是直接覆盖线上文件，而是通过一个的规则成为新建的文件。</p>
<p>如：我要上线覆盖的文件夹为 vote，那么先将代码都拷贝到vote.online文件下（各个机器），其他模块的代码拷贝到其他对应的文件夹下。待所有要上线的代码都准备好后，然后执行mv的操作，将要上线的代码覆盖到真正的文件夹下。在这个过程中，虽然要有时长，但这个时间要小很多。</p>
<p>借助自动化上线，这种方式要比现有的上线要快很多。上线时间差越小，对线上服务的影响越小。</p>
<h2>特殊情况</h2>
<p>上面讲的方式虽然将时间差缩小了很多，但还是有一些很小的时间差。对于一般的服务大家都是可以接受的，但对于一些交易类的服务（如：电子商务，金融），这种时间差还是不能接受的。对于这种要求非常严格的服务估计还是只能夜里停服务上线了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/reduce-bad-online-service-on-upgrade.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何减少前端异步请求的数量</title>
		<link>http://www.welefen.com/reduce-asyn-request.html</link>
		<comments>http://www.welefen.com/reduce-asyn-request.html#comments</comments>
		<pubDate>Tue, 07 Sep 2010 01:57:25 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[前端]]></category>
		<category><![CDATA[异步请求]]></category>
		<category><![CDATA[百度]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=341</guid>
		<description><![CDATA[开发模式 在前端开发中，一条很重要的优化原则就是减少HTTP请求数。但在实际开发中，有时候不得不用大量的异步请求。这里的异步请求所指的都是页面加载时的，之后用户操作过程中所发生的异步请求并不影响加载的速度。 在百度这边，由于FE需要写模板。所以很多时候有些功能如果有接口了，RD同学就要你使用异步接口。但异步接口使用多了就会影响页面的性能。比如说百度空间个人中心在页面加载时差不多要处理10个异步请求。这个数量是非常大的。如果减少这些异步请求的数量成为了优化的重点之重。 实现方案 目前想到一条比较可行的实现方案是通过一个公用的代理页面，前端在处理时将这些异步请求分组去处理。代理页面获取到打包的URL，然后服务器端去请求，最后将合并后的数据输出。 在服务器端去请求，由于数据是服务器对服务器的，数据网络传输时间可以忽略不计。 实现代码 if(typeof Space == 'undefined') window.Space = {}; Space.asynJs = function(){ &#160; &#160; var&#160;_isStart = false, &#160; &#160; &#160; &#160; stack = []; &#160; &#160; function&#160;start(){ &#160; &#160; &#160; &#160; if(_isStart){ &#160; &#160; &#160; &#160; &#160; &#160; throw&#160;new Error('asynJs request is start.'); &#160; &#160; &#160; &#160; &#160; &#160; return&#160;false; [...]]]></description>
			<content:encoded><![CDATA[<h2>开发模式</h2>
<p>在前端开发中，一条很重要的优化原则就是减少HTTP请求数。但在实际开发中，有时候不得不用大量的异步请求。这里的异步请求所指的都是页面加载时的，之后用户操作过程中所发生的异步请求并不影响加载的速度。</p>
<p>在百度这边，由于FE需要写模板。所以很多时候有些功能如果有接口了，RD同学就要你使用异步接口。但异步接口使用多了就会影响页面的性能。比如说百度空间个人中心在页面加载时差不多要处理10个异步请求。这个数量是非常大的。如果减少这些异步请求的数量成为了优化的重点之重。</p>
<h2>实现方案</h2>
<p>目前想到一条比较可行的实现方案是通过一个公用的代理页面，前端在处理时将这些异步请求分组去处理。代理页面获取到打包的URL，然后服务器端去请求，最后将合并后的数据输出。</p>
<p>在服务器端去请求，由于数据是服务器对服务器的，数据网络传输时间可以忽略不计。</p>
<p><img class="alignnone size-full wp-image-355" title="asyn-request" src="http://www.welefen.com/wp-content/uploads/2010/09/asyn-request.png" alt="" width="682" height="303" /></p>
<h2>实现代码</h2>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Green;">typeof</span><span style="color: Gray;"> </span><span style="color: Blue;">Space</span><span style="color: Gray;"> == </span><span style="color: #8b0000;">'</span><span style="color: Red;">undefined</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Teal;">window</span><span style="color: Gray;">.</span><span style="color: Blue;">Space</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">Space</span><span style="color: Gray;">.</span><span style="color: Blue;">asynJs</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">_isStart</span><span style="color: Gray;"> = </span><span style="color: Green;">false</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">stack</span><span style="color: Gray;"> = </span><span style="color: Olive;">[]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">function</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">start</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">_isStart</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">throw</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">new</span><span style="color: Gray;"> </span><span style="color: Blue;">Error</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">asynJs request is start.</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">false</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">_isStart</span><span style="color: Gray;"> = </span><span style="color: Green;">true</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">i</span><span style="color: Gray;"> = </span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Blue;">len</span><span style="color: Gray;"> = </span><span style="color: Blue;">stack</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;"> &lt; </span><span style="color: Blue;">len</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;">++</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: Blue;">stack</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">])</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">continue</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">setTimeout</span><span style="color: Olive;">(</span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: #ffa500;">//如果该组只有一条记录，就不用走通用代理了。</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">stack</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;"> == </span><span style="color: Maroon;">1</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">baidu</span><span style="color: Gray;">.</span><span style="color: Blue;">sio</span><span style="color: Gray;">.</span><span style="color: Blue;">callByServer</span><span style="color: Olive;">(</span><span style="color: Blue;">decodeURIComponent</span><span style="color: Olive;">(</span><span style="color: Blue;">url</span><span style="color: Olive;">))</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Green;">else</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">url</span><span style="color: Gray;"> = </span><span style="color: #8b0000;">'</span><span style="color: Red;">url[]=</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> + </span><span style="color: Blue;">stack</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span><span style="color: Blue;">join</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">&amp;url[]=</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">baidu</span><span style="color: Gray;">.</span><span style="color: Blue;">page</span><span style="color: Gray;">.</span><span style="color: Blue;">loadJsFile</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">http://hi.baidu.com/st/asynproxy.php?</span><span style="color: #8b0000;">'</span><span style="color: Gray;"> + </span><span style="color: Blue;">url</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">,</span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">function</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">load</span><span style="color: Olive;">(</span><span style="color: Blue;">url</span><span style="color: Gray;">, </span><span style="color: Blue;">group</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">group</span><span style="color: Gray;"> = </span><span style="color: Blue;">group</span><span style="color: Gray;"> | </span><span style="color: Maroon;">0</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">url</span><span style="color: Gray;"> = </span><span style="color: Blue;">encodeURIComponent</span><span style="color: Olive;">(</span><span style="color: Blue;">url</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: Blue;">stack</span><span style="color: Olive;">[</span><span style="color: Blue;">group</span><span style="color: Olive;">]){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">stack</span><span style="color: Olive;">[</span><span style="color: Blue;">group</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Olive;">[</span><span style="color: Blue;">url</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Green;">else</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">stack</span><span style="color: Olive;">[</span><span style="color: Blue;">group</span><span style="color: Olive;">]</span><span style="color: Gray;">.</span><span style="color: Blue;">push</span><span style="color: Olive;">(</span><span style="color: Blue;">url</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">load</span><span style="color: Gray;">:</span><span style="color: Blue;">load</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">start</span><span style="color: Gray;">:</span><span style="color: Blue;">start</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}()</span></li></ol></div>
<p>该实现方式就是提供了2个方法load和start，load用于填充要请求的异步接口，start在页面底部启动请求。因为页面一般都分成头，中，尾3个部分，所以start方法可以在尾部文件里直接调用就可以了。</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">Space</span><span style="color: Gray;">.</span><span style="color: Blue;">asynJs</span><span style="color: Gray;">.</span><span style="color: Blue;">load</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">http://pageurl1</span><span style="color: #8b0000;">'</span><span style="color: Gray;">, </span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span></li>
<li><span style="color: Blue;">Space</span><span style="color: Gray;">.</span><span style="color: Blue;">asynJs</span><span style="color: Gray;">.</span><span style="color: Blue;">load</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">http://pageurl2</span><span style="color: #8b0000;">'</span><span style="color: Gray;">, </span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span></li>
<li><span style="color: Blue;">Space</span><span style="color: Gray;">.</span><span style="color: Blue;">asynJs</span><span style="color: Gray;">.</span><span style="color: Blue;">load</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">http://pageurl3</span><span style="color: #8b0000;">'</span><span style="color: Gray;">, </span><span style="color: Maroon;">2</span><span style="color: Olive;">)</span></li>
<li><span style="color: #ffa500;">//在页面最底部启动请求</span></li>
<li><span style="color: Blue;">Space</span><span style="color: Gray;">.</span><span style="color: Blue;">asynJs</span><span style="color: Gray;">.</span><span style="color: Blue;">start</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li></ol></div>
<h2>PHP端的实现</h2>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">&lt;?php</span></li>
<li><span style="color: #ffa500;">//url is array</span></li>
<li><span style="color: #00008b;">$urls</span><span style="color: Gray;"> = </span><span style="color: #00008b;">$_GET</span><span style="color: Olive;">[</span><span style="color: #8b0000;">'</span><span style="color: Red;">url</span><span style="color: #8b0000;">'</span><span style="color: Olive;">]</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">//经过白名单过滤后的URL</span></li>
<li><span style="color: #00008b;">$urls</span><span style="color: Gray;"> = </span><span style="color: Blue;">apply_domain_filter</span><span style="color: Olive;">(</span><span style="color: #00008b;">$urls</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">//实例化Curl类</span></li>
<li><span style="color: #00008b;">$curl</span><span style="color: Gray;"> = </span><span style="color: Green;">new</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">Curl</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: #00008b;">$contents</span><span style="color: Gray;"> = </span><span style="color: Green;">array</span><span style="color: Olive;">()</span><span style="color: Gray;">;</span></li>
<li><span style="color: Green;">foreach</span><span style="color: Olive;">(</span><span style="color: #00008b;">$urls</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">as</span><span style="color: Gray;"> </span><span style="color: #00008b;">$url</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">//需要配置对应URL的transmit</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #ffa500;">//请求时带上传递过来的Cookie</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: #00008b;">$contents</span><span style="color: Olive;">[]</span><span style="color: Gray;"> = </span><span style="color: #00008b;">$curl</span><span style="color: Gray;">-&gt;</span><span style="color: Blue;">get</span><span style="color: Olive;">(</span><span style="color: #00008b;">$url</span><span style="color: Gray;">, </span><span style="color: #00008b;">$_COOKIE</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Green;">echo</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">join</span><span style="color: Olive;">(</span><span style="color: #8b0000;">'</span><span style="color: Red;">;</span><span style="color: #8b0000;">'</span><span style="color: Gray;">, </span><span style="color: #00008b;">$contents</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Blue;">?&gt;</span></li></ol></div>
<h2>额外的收益</h2>
<p>目前一些框架(tangram)里domready时执行一些函数时并没有提供函数排序的功能，这样就不能实现重要的异步请求先加载不重要的请求后加载的功能。目前百度空间app平台这边实现方式是通过setTimeout延时来执行。如果设置的时间较短，各个浏览器表现的不一样。如果设置的时间比较长，有会影响页面加载的时间。</p>
<p>通过现在的这种方式后，不光实现了异步接口分组的功能，同时实现了重要的先加载，不重要的后加载。<br />
先加载的东西只要第二个参数传值小一些就可以了。</p>
<h2>风险</h2>
<p>由于通用代理管理的是获取URL然后请求的工作，所以如果在后端不做一些判断的话可能引发一些风险，甚至XSS漏洞。目前想到的主要是2点。</p>
<p>1、通用代理要判断域，非白名单制定域不予请求<br />
2、返回时必须设置header为application/javascript来阻止直接请求的XSS漏洞</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/reduce-asyn-request.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>巧用XSS为实际需求服务</title>
		<link>http://www.welefen.com/use-xss-for-program.html</link>
		<comments>http://www.welefen.com/use-xss-for-program.html#comments</comments>
		<pubDate>Sat, 26 Jun 2010 01:39:14 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[img]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=283</guid>
		<description><![CDATA[昨天早上和JerryQu骑车上班的途中聊天，他这几天遇到一个特殊的需求。 页面中调用一个通过CMS发布的callback，callback返回一段字符串内容，然后页面拿到内容后直接innerHTML塞到某个ID里面去。本身这是个很简单的需求。 但是现在需求复杂了，希望callback返回内容中有一段脚本，用来操作页面的DOM。不想改变页面的原因是，要走整套上线流程，非常麻烦，你们懂的。 也就是本事返回的内容是“这是返回的内容”，现在变成“这是返回的内容&#60;script&#62;这里增加一些脚本操作页面&#60;/script&#62;”，但是这样直接innerHTML进去的话是不被执行的。 一种解决方案是，将script标签变成iframe,嵌套一个新的页面（这个页面也是通过CMS发布，所以也很方便），然后iframe的页面用来操作父页面的DOM（当然是在同一个域下）。 后来想到了一种解决方案。利用XSS经常用的方式，插入一个img标签，设置src为一个不存在的URL，然后再onerror事件里操作页面的DOM，如： 返回内容为“这是返回的内容&#60;img src=&#8221;h&#8221; onerror=&#8221;这里的脚本用来操作页面DOM&#8221;&#62;”。 经测试，一切OK。]]></description>
			<content:encoded><![CDATA[<p>昨天早上和<a href="http://www.qgy18.com" target="_blank">JerryQu</a>骑车上班的途中聊天，他这几天遇到一个特殊的需求。</p>
<p>页面中调用一个通过CMS发布的callback，callback返回一段字符串内容，然后页面拿到内容后直接innerHTML塞到某个ID里面去。本身这是个很简单的需求。</p>
<p>但是现在需求复杂了，希望callback返回内容中有一段脚本，用来操作页面的DOM。不想改变页面的原因是，要走整套上线流程，非常麻烦，你们懂的。</p>
<p>也就是本事返回的内容是“这是返回的内容”，现在变成“这是返回的内容&lt;script&gt;这里增加一些脚本操作页面&lt;/script&gt;”，但是这样直接innerHTML进去的话是不被执行的。</p>
<p>一种解决方案是，将script标签变成iframe,嵌套一个新的页面（这个页面也是通过CMS发布，所以也很方便），然后iframe的页面用来操作父页面的DOM（当然是在同一个域下）。</p>
<p>后来想到了一种解决方案。利用XSS经常用的方式，插入一个img标签，设置src为一个不存在的URL，然后再onerror事件里操作页面的DOM，如：</p>
<p>返回内容为“这是返回的内容&lt;img src=&#8221;h&#8221; onerror=&#8221;这里的脚本用来操作页面DOM&#8221;&gt;”。</p>
<p>经测试，一切OK。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/use-xss-for-program.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>按字节截取字符串</title>
		<link>http://www.welefen.com/substr-by-byte.html</link>
		<comments>http://www.welefen.com/substr-by-byte.html#comments</comments>
		<pubDate>Tue, 09 Mar 2010 04:02:58 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[byte]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=273</guid>
		<description><![CDATA[在JS中，由于中文和英文是同等对待的，但有时候我们希望是一个中文按两个字节算，这就出现了按字节截取字符串的功能。下面列举了 2种实现方式。 循环检测 这种实现方式来自于Tangram，具体实现如下： baidu.string.getByteLength = function (source) { &#160;&#160; return&#160;String(source).replace(/[^\x00-\xff]/g, &#34;ci&#34;).length; &#160;&#160; }; /* * Tangram * Copyright 2009 Baidu Inc. All rights reserved. * * path: baidu/string/subByte.js * author: dron, erik * version: 1.1.0 * date: 2009/11/30 */ /** * 对目标字符串按gbk编码截取字节长度 * * @param {string} source 目标字符串 * @param {number} length 需要截取的字节长度 * [...]]]></description>
			<content:encoded><![CDATA[<p>在JS中，由于中文和英文是同等对待的，但有时候我们希望是一个中文按两个字节算，这就出现了按字节截取字符串的功能。下面列举了 2种实现方式。</p>
<h2>循环检测</h2>
<p>这种实现方式来自于Tangram，具体实现如下：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">baidu</span><span style="color: Gray;">.</span><span style="color: Blue;">string</span><span style="color: Gray;">.</span><span style="color: Blue;">getByteLength</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Blue;">source</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Teal;">String</span><span style="color: Olive;">(</span><span style="color: Blue;">source</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">replace</span><span style="color: Olive;">(</span><span style="color: #8b0000;">/</span><span style="color: Red;">[^\x00-\xff]</span><span style="color: #8b0000;">/g</span><span style="color: Gray;">, </span><span style="color: #8b0000;">&quot;</span><span style="color: Red;">ci</span><span style="color: #8b0000;">&quot;</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: #ffa500;">/*</span></li>
<li><span style="color: #ffa500;">* Tangram</span></li>
<li><span style="color: #ffa500;">* Copyright 2009 Baidu Inc. All rights reserved.</span></li>
<li><span style="color: #ffa500;">*</span></li>
<li><span style="color: #ffa500;">* path: baidu/string/subByte.js</span></li>
<li><span style="color: #ffa500;">* author: dron, erik</span></li>
<li><span style="color: #ffa500;">* version: 1.1.0</span></li>
<li><span style="color: #ffa500;">* date: 2009/11/30</span></li>
<li><span style="color: #ffa500;">*/</span></li>
<li><span style="color: #ffa500;">/**</span></li>
<li><span style="color: #ffa500;">* 对目标字符串按gbk编码截取字节长度</span></li>
<li><span style="color: #ffa500;">*</span></li>
<li><span style="color: #ffa500;">* @param {string} source 目标字符串</span></li>
<li><span style="color: #ffa500;">* @param {number} length 需要截取的字节长度</span></li>
<li><span style="color: #ffa500;">* @return {string} 字符串截取结果</span></li>
<li><span style="color: #ffa500;">*/</span></li>
<li><span style="color: Blue;">baidu</span><span style="color: Gray;">.</span><span style="color: Blue;">string</span><span style="color: Gray;">.</span><span style="color: Blue;">subByte</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">source</span><span style="color: Gray;">, </span><span style="color: Blue;">length</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Blue;">source</span><span style="color: Gray;"> = </span><span style="color: Teal;">String</span><span style="color: Olive;">(</span><span style="color: Blue;">source</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">getLen</span><span style="color: Gray;"> = </span><span style="color: Blue;">baidu</span><span style="color: Gray;">.</span><span style="color: Blue;">string</span><span style="color: Gray;">.</span><span style="color: Blue;">getByteLength</span><span style="color: Gray;">, </span><span style="color: Blue;">i</span><span style="color: Gray;">, </span><span style="color: Blue;">len</span><span style="color: Gray;">, </span><span style="color: Blue;">current</span><span style="color: Gray;">, </span><span style="color: Blue;">next</span><span style="color: Gray;">, </span><span style="color: Blue;">currentLen</span><span style="color: Gray;">, </span><span style="color: Blue;">nextLen</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Green;">if</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">length</span><span style="color: Gray;"> &lt; </span><span style="color: Maroon;">0</span><span style="color: Gray;"> || </span><span style="color: Blue;">getLen</span><span style="color: Olive;">(</span><span style="color: Blue;">source</span><span style="color: Olive;">)</span><span style="color: Gray;"> &lt;= </span><span style="color: Blue;">length</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">source</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Blue;">len</span><span style="color: Gray;"> = </span><span style="color: Blue;">source</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp;&nbsp; </span><span style="color: Green;">for</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">i</span><span style="color: Gray;"> = </span><span style="color: Teal;">Math</span><span style="color: Gray;">.</span><span style="color: Blue;">floor</span><span style="color: Olive;">(</span><span style="color: Blue;">length</span><span style="color: Gray;"> </span><span style="color: #8b0000;">/</span><span style="color: Red;"> 2) - 1; i &lt; len; i++) {</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; current = next || source.substr(0, i);</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; currentLen = nextLen || getLen(current);</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; if (currentLen == length) {</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; return current;</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; }</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; else {</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; next = source.substr(0, i + 1);</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; nextLen = getLen(next);</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; if (nextLen &gt; length) {</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return current;</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; }</span></li>
<li><span style="color: Red;">&nbsp; &nbsp; &nbsp; }</span></li>
<li><span style="color: Red;">&nbsp;&nbsp; return source;</span></li>
<li><span style="color: Red;">&nbsp;&nbsp; };</span></li></ol></div>
<p>baidu.string是字符串常见操作的对象。</p>
<h2>正则替换</h2>
<p>这种方式的实现原理是先将中文替换成中文加个空格，这样变相的将一个中文变成了2个字节，然后在这个基础上截取，截取完成后在将中文加空格变成中文。</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Blue;">baidu</span><span style="color: Gray;">.</span><span style="color: Blue;">string</span><span style="color: Gray;">.</span><span style="color: Blue;">subByte1</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">source</span><span style="color: Gray;">, </span><span style="color: Blue;">length</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Olive;">(</span><span style="color: Blue;">source</span><span style="color: Gray;">+</span><span style="color: #8b0000;">''</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">substr</span><span style="color: Olive;">(</span><span style="color: Maroon;">0</span><span style="color: Gray;">,</span><span style="color: Blue;">length</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">replace</span><span style="color: Olive;">(</span><span style="color: #8b0000;">/</span><span style="color: Red;">([^\x00-\xff])</span><span style="color: #8b0000;">/g</span><span style="color: Gray;">,</span><span style="color: #8b0000;">'</span><span style="color: Red;">$1 </span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">substr</span><span style="color: Olive;">(</span><span style="color: Maroon;">0</span><span style="color: Gray;">,</span><span style="color: Blue;">length</span><span style="color: Olive;">)</span><span style="color: Gray;">.</span><span style="color: Blue;">replace</span><span style="color: Olive;">(</span><span style="color: #8b0000;">/</span><span style="color: Red;">([^\x00-\xff]) </span><span style="color: #8b0000;">/g</span><span style="color: Gray;">,</span><span style="color: #8b0000;">'</span><span style="color: Red;">$1</span><span style="color: #8b0000;">'</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>这种实现方式不管是从代码量上还是从效率上都要比第一种高很多，<a href="/examples/subbyte/index.html" target="_blank">这里有个测试案例</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/substr-by-byte.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>js动态创建类和实例化</title>
		<link>http://www.welefen.com/js%e5%8a%a8%e6%80%81%e5%88%9b%e5%bb%ba%e7%b1%bb%e5%92%8c%e5%ae%9e%e4%be%8b%e5%8c%96.html</link>
		<comments>http://www.welefen.com/js%e5%8a%a8%e6%80%81%e5%88%9b%e5%bb%ba%e7%b1%bb%e5%92%8c%e5%ae%9e%e4%be%8b%e5%8c%96.html#comments</comments>
		<pubDate>Wed, 24 Feb 2010 08:39:34 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[instance]]></category>
		<category><![CDATA[js]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=265</guid>
		<description><![CDATA[在js中，创建一个类和实例化该类一般方式是： var cls = function(){} cls.prototype = { attr:'', method:function(){} } var&#160;clsInstance = new cls; 这种方式简单明了，但如果类很多的话就比较痛苦了，并且代码看起来不够优化。 动态创建类 动态创建类实际上类似于一种代理的模式，代码如下： var Fath = function(methods){ &#160; &#160; var&#160;cls = function(){ &#160; &#160; &#160; &#160; return&#160;new fn(arguments); &#160; &#160; }, &#160; &#160; fn = function(args){ &#160; &#160; &#160; &#160; return&#160;this.init &#38;&#38; this.init.apply &#38;&#38; this.init.apply(this,args); &#160; &#160; }; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>在js中，创建一个类和实例化该类一般方式是：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">cls</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(){}</span></li>
<li><span style="color: Blue;">cls</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;"> = </span><span style="color: Olive;">{</span></li>
<li><span style="color: Blue;">attr</span><span style="color: Gray;">:</span><span style="color: #8b0000;">''</span><span style="color: Gray;">,</span></li>
<li><span style="color: Blue;">method</span><span style="color: Gray;">:</span><span style="color: Green;">function</span><span style="color: Olive;">(){}</span></li>
<li><span style="color: Olive;">}</span></li>
<li><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">clsInstance</span><span style="color: Gray;"> = </span><span style="color: Green;">new</span><span style="color: Gray;"> </span><span style="color: Blue;">cls</span><span style="color: Gray;">;</span></li></ol></div>
<p>这种方式简单明了，但如果类很多的话就比较痛苦了，并且代码看起来不够优化。</p>
<h2>动态创建类</h2>
<p>动态创建类实际上类似于一种代理的模式，代码如下：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">Fath</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">methods</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">var</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">cls</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">new</span><span style="color: Gray;"> </span><span style="color: Blue;">fn</span><span style="color: Olive;">(</span><span style="color: Blue;">arguments</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">,</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">fn</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">args</span><span style="color: Olive;">){</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Green;">this</span><span style="color: Gray;">.</span><span style="color: Blue;">init</span><span style="color: Gray;"> &amp;&amp; </span><span style="color: Green;">this</span><span style="color: Gray;">.</span><span style="color: Blue;">init</span><span style="color: Gray;">.</span><span style="color: Blue;">apply</span><span style="color: Gray;"> &amp;&amp; </span><span style="color: Green;">this</span><span style="color: Gray;">.</span><span style="color: Blue;">init</span><span style="color: Gray;">.</span><span style="color: Blue;">apply</span><span style="color: Olive;">(</span><span style="color: Green;">this</span><span style="color: Gray;">,</span><span style="color: Blue;">args</span><span style="color: Olive;">)</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Blue;">fn</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;"> = </span><span style="color: Blue;">cls</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;"> = </span><span style="color: Blue;">methods</span><span style="color: Gray;"> || </span><span style="color: Olive;">{}</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Green;">try</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Green;">return</span><span style="color: Gray;">&nbsp;</span><span style="color: Blue;">cls</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span><span style="color: Green;">finally</span><span style="color: Olive;">{</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="color: Blue;">cls</span><span style="color: Gray;"> = </span><span style="color: Green;">null</span><span style="color: Gray;">;</span></li>
<li><span style="color: Gray;">&nbsp; &nbsp; </span><span style="color: Olive;">}</span></li>
<li><span style="color: Olive;">}</span></li></ol></div>
<p>创建一个类：<br />
var TestClass = Fath(methods) //这里的methods是方法或者属性集合，是一个静态对象<br />
实例化该类：<br />
var testInstance = TestClass(params) //这里的params是传进去的形参<br />
通过这种方式后，一个好处就是实例化类的时候不用再使用new了，当然使用new也是可以的，作用的等价的。避免了到处是new和prototype的好处。<br />
性能上在1K数量级上没有很大的区别。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/js%e5%8a%a8%e6%80%81%e5%88%9b%e5%bb%ba%e7%b1%bb%e5%92%8c%e5%ae%9e%e4%be%8b%e5%8c%96.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>select节点clone全解析</title>
		<link>http://www.welefen.com/select-clone.html</link>
		<comments>http://www.welefen.com/select-clone.html#comments</comments>
		<pubDate>Fri, 18 Dec 2009 03:01:35 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[clone]]></category>
		<category><![CDATA[cloneNode]]></category>
		<category><![CDATA[select]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=177</guid>
		<description><![CDATA[在开发ns-log项目中，统计分类有复制的功能。由于之前的统计分类中的数据是通过JS赋值进去的，之后用户可能又进行了修改，发现进行节点克隆时，出现了 无法复制select下拉框值的怪异现象。本文对这个怪异现象进行解析和给出解决办法。 问题现状 使用节点的cloneNode(true/false)进行克隆时，目前是下面的表现情况： select为设置初始值或者初始值是第一个option。 表现：各大浏览器都没什么问题。 select初始值不是在第一个option。 表现：IE下无法克隆，其他内核的浏览器没什么问题。 select的值被用户或者JS修改。 表现：各个浏览器均无法克隆到真确的值。值结果跟第二条结果相同。 IE的特殊处理 对于上面第二条，初始值不在第一个option时无法克隆的情况，确实是IE的一个Bug，相信不少人都遇到过这样的问题。并且IE下使用cloneNode方法时，还有Event方面的问题，所以差不多可以放弃使用这个方法。 IE下可以使用节点的outerHTML属性解决这个问题，它能够实时的获取节点的内容，哪怕是select的值被用户或者程序改变。下面给出简单的实现。 function clone(node){ var div = document.createElement(&#8216;div&#8217;); div.innerHTML = node.outerHTML; return div.childNodes[0]; } 其他内核浏览器的处理 既然IE内核的浏览器可以通过outerHTML属性来解决这个问题，那FF等浏览器可以通过类似的方法来实现吗？虽然FF等浏览器没有outerHTML属性，但是可以通过innerHTML属性实现，如： function getOuterHTML(node){ var div = document.createElement(&#8216;div&#8217;); div.appendChild(node); try{ return div.innerHTML; }catch(e){ div = null; } } 答案是否定。 为什么会这样呢？难道是FF等浏览器的bug？ 下面还是从W3C中对cloneNode方法,select标签，属性的定义进行说明。 下面引用的资料都是来自HTML5草案，HTML4或者XHTML对这些没有太多详细的定义。虽然是HTML5的，但这些节点跟以前没什么变化。 W3C中的cloneNode 具体链接：http://www.w3.org/TR/DOM-Level-2-Core/core.html 里面有2点比较重要： 克隆时会拷贝节点的所有属性和对应的值。 如果cloneNode方法的参数为true，会通过递归的方法克隆子节点。 W3C中的select节点 具体链接：http://dev.w3.org/html5/spec/forms.html#the-select-element W3C对于属性的定义有2种，一种是内容性属性（Content [...]]]></description>
			<content:encoded><![CDATA[<p>在开发ns-log项目中，统计分类有复制的功能。由于之前的统计分类中的数据是通过JS赋值进去的，之后用户可能又进行了修改，发现进行节点克隆时，出现了 无法复制select下拉框值的怪异现象。本文对这个怪异现象进行解析和给出解决办法。</p>
<h2>问题现状</h2>
<p>使用节点的cloneNode(true/false)进行克隆时，目前是下面的表现情况：</p>
<ol>
<li>select为设置初始值或者初始值是第一个option。<br />
表现：各大浏览器都没什么问题。</li>
<li>select初始值不是在第一个option。<br />
表现：IE下无法克隆，其他内核的浏览器没什么问题。</li>
<li>select的值被用户或者JS修改。<br />
表现：各个浏览器均无法克隆到真确的值。值结果跟第二条结果相同。</li>
</ol>
<p><span id="more-177"></span></p>
<h2>IE的特殊处理</h2>
<p>对于上面第二条，初始值不在第一个option时无法克隆的情况，确实是IE的一个Bug，相信不少人都遇到过这样的问题。并且IE下使用cloneNode方法时，还有Event方面的问题，所以差不多可以放弃使用这个方法。</p>
<p>IE下可以使用节点的outerHTML属性解决这个问题，它能够实时的获取节点的内容，哪怕是select的值被用户或者程序改变。下面给出简单的实现。</p>
<p>function clone(node){<br />
var div = document.createElement(&#8216;div&#8217;);<br />
div.innerHTML = node.outerHTML;<br />
return div.childNodes[0];<br />
}</p>
<h2>其他内核浏览器的处理</h2>
<p>既然IE内核的浏览器可以通过outerHTML属性来解决这个问题，那FF等浏览器可以通过类似的方法来实现吗？虽然FF等浏览器没有outerHTML属性，但是可以通过innerHTML属性实现，如：</p>
<p>function getOuterHTML(node){<br />
var div = document.createElement(&#8216;div&#8217;);<br />
div.appendChild(node);<br />
try{<br />
return div.innerHTML;<br />
}catch(e){<br />
div = null;<br />
}<br />
}</p>
<p>答案是否定。</p>
<p>为什么会这样呢？难道是FF等浏览器的bug？</p>
<p>下面还是从W3C中对cloneNode方法,select标签，属性的定义进行说明。</p>
<p><span style="color: #ff0000;">下面引用的资料都是来自HTML5草案，HTML4或者XHTML对这些没有太多详细的定义。虽然是HTML5的，但这些节点跟以前没什么变化。</span></p>
<h2>W3C中的cloneNode</h2>
<p align="left">具体链接：<a href="http://www.w3.org/TR/DOM-Level-2-Core/core.html" target="_blank">http://www.w3.org/TR/DOM-Level-2-Core/core.html</a></p>
<p align="left">里面有2点比较重要：</p>
<ol>
<li>克隆时会拷贝节点的所有<span style="color: #ff0000;">属性</span>和对应的值。</li>
<li>如果cloneNode方法的参数为true，会通过递归的方法克隆子节点。</li>
</ol>
<h2>W3C中的select节点</h2>
<p>具体链接：<a href="http://dev.w3.org/html5/spec/forms.html#the-select-element" target="_blank">http://dev.w3.org/html5/spec/forms.html#the-select-element</a></p>
<p>W3C对于属性的定义有2种，一种是内容性属性（Content attributes），另一种是操作性属性（未给出具体的命名，这里暂时使用这个名字）。</p>
<p>对于select标签，内容性属性主要有：Global attributes，autofocus，disabled，form，multiple，name，size。其中Global attributes包含一些常用的属性(accesskey,class,contenteditable,contextmenu,dir,draggable,hidden,id,itemid,<br />
itemprop,itemref,itemscope,itemtype,lang,spellcheck,style,tabindex,title)，这些属性是所有标签里都包含的，具体的见<a href="http://dev.w3.org/html5/spec/dom.html#global-attributes" target="_blank">http://dev.w3.org/html5/spec/dom.html#global-attributes </a></p>
<p>而selectedIndex和value都属于操作性属性，这两个属性获取值的方式如下：</p>
<blockquote><dl>
<dt><var>select</var> . <code title="dom-select-selectedIndex"><a href="http://dev.w3.org/html5/spec/forms.html#dom-select-selectedindex">selectedIndex</a></code> [ = <var>value</var> ]</dt>
<dd>Returns the index of the first selected item, if any, or     −1 if there is no selected item.</p>
<p>Can be set, to change the selection.</p>
</dd>
<dt><var>select</var> . <code title="dom-select-value"><a href="http://dev.w3.org/html5/spec/forms.html#dom-select-value">value</a></code> [ = <var>value</var> ]</dt>
<dd>Returns the <a title="concept-fe-value" href="http://dev.w3.org/html5/spec/forms.html#concept-fe-value">value</a> of the     first selected item, if any, or the empty string if there is no     selected item.</p>
<p>Can be set, to change the selection.</p>
</dd>
</dl>
</blockquote>
<h2>内容性属性和操作性属性的区别</h2>
<p>给节点添加属性有两种方式，如下面所示：</p>
<p>var div = document.createElement(&#8216;div&#8217;)<br />
div.id = &#8216;welefen&#8217;; //直接加属性<br />
div.setAttribute(&#8216;id&#8217;,'welefen&#8217;); //通过setAttribute方法添加属性</p>
<p>对于内容性属性，这两种方法是完全相同的。</p>
<p>但对于操作性属性，第一种方式只会将属性添加在操作范围内，当把节点添加到DOM中，属性就失效了。</p>
<p>由于selectedIndex和value都是操作性属性，如果select的值被用户或者程序改变，clone时当前的值是无法带过去的。所以才会出现了无法克隆值的情况。并且也无法使用innerHTML来克隆值，因为innerHTML的原理跟这个是一样的。</p>
<p>innerHTML实现原理请看这里：<a href="http://www.w3.org/TR/2008/WD-html5-20080610/serializing.html#html-fragment" target="_blank">http://www.w3.org/TR/2008/WD-html5-20080610/serializing.html#html-fragment</a></p>
<h2>FF等浏览器解决方案</h2>
<p>目前有2中解决方案，第一种是在select绑定change事件，触发change的时候，改变options里的selected属性，当然这种方法是很不可取的。另一种方案就是在克隆时获取元素的值，然后再赋值到克隆后的对象上去。</p>
<h2>总结</h2>
<p>当前出现这个情况的时候，以为是FF等浏览器的bug。当后来仔细想想，应该不会这样的情况，后来反复查看W3C相关的文档，终于确认了这一问题。下面给出完整的解决方案：</p>
<p>function cloneSelect(select){<br />
if(document.all){<br />
var html = select.outerHTML,<br />
div = document.createElement(&#8216;div&#8217;);<br />
div.innerHTML = html;<br />
return div.childNodes[0];<br />
}<br />
var cloneSelect = select.cloneNode(true);<br />
cloneSelect.selectedIndex = select.selectedIndex;<br />
cloneSelect.value = select.value;<br />
return cloneSelect;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/select-clone.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript中toInt的几种方法</title>
		<link>http://www.welefen.com/javascript-toint-method.html</link>
		<comments>http://www.welefen.com/javascript-toint-method.html#comments</comments>
		<pubDate>Wed, 16 Dec 2009 08:20:26 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tonumber]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=166</guid>
		<description><![CDATA[在javascript中，如果要将一个字符串转变成数字，一般是通过parseInt这个函数进行。但如果对输入串有很高确定性的话，其实可以用更简单的方法。如：只是将字符串“123”变成数字123。下面给出具体的说明。 parseInt函数 parseInt函数是专门用来处理将字符串变成整型的。具体请见：ECMA-262 P114。 支持八进制和十六进制，如：&#8217;0111&#8242;，&#8217;0&#215;111&#8242;。 支持非正数。如：&#8217;-111&#8242;。 支持数字后还有字符串，如：&#8217;111abc&#8217;。 支持第二个参数，是传递的转换进制，数值为2到36。如：parseInt(&#8217;111&#8242;,2)，即将111转换为二进制。 忽略前面的空白字符，如：\n，\t，\r。 如果无法将字符串转换为一个数值，则返回NaN。 一元操作符“+” 在javascript中，“+”号即可以作为二元操作符，又可以作为一元操作符。作为一元操作符的时候，就是将对象变成数值形式的。具体见：ECMA-262 P82。 其实执行+的时候，调用JS引擎的ToNumber函数。 true/false转成1/0。 null转成0。 支持非正数。 忽略前面的空白字符。 支持16进制，八进制会当十进制处理。 &#8220;111&#8243;转换成111，其他情况基本都是 NaN。 Number构造器 当number构造器当函数使用时，是将其他对象转化成数值。转换原理跟一元操作符&#8221;+&#8221;完全一样，因为都是调用JS引擎ToNumber函数。所以这个方式基本不用，因为使用它比使用“+”要多7个字符。 二进制操作符“&#124;” 使用二进制操作符“&#124;”结合0可以将对象转换成整形的。如&#8217;111&#8242;&#124;0。 true/false转换成1/0。 忽略前面的特殊字符。 支持16进制，八进制会当十进制处理。 null转成0。 支持非正数。 不能转换成整型的，则返回为0。如：&#8217;111abc&#8217;结果为0。 二进制操作符“&#62;&#62;” 使用二进制操作符“&#62;&#62;”结合0可以将对象转换成整形的。如&#8217;111&#8242;&#62;&#62;0。 true/false转换成1/0。 忽略前面的特殊字符。 支持16进制，八进制会当十进制处理。 null转成0。 支持非正数。 不能转换成整型的，则返回为0。如：&#8217;111abc&#8217;结果为0。 二进制操作符“&#62;&#62;&#62;” 使用二进制操作符“&#62;&#62;&#62;”结合0可以将对象转换成整形的。如&#8217;111&#8242;&#62;&#62;&#62;0。 true/false转换成1/0。 忽略前面的特殊字符。 支持16进制，八进制会当十进制处理。 null转成0。 非正数的时候则转换为2^32-概数的绝对值。如：&#8217;-111&#8242;&#62;&#62;&#62;0为4294967185。 不能转换成整型的，则返回为0。如：&#8217;111abc&#8217;结果为0。 测试结果 对于转换的对象数字加字符或者其他类型的，只能用parseInt转换。 对于一般的转化，如将“123”转化成123时，有如下的测试结果： parseInt + &#124; &#62;&#62; &#62;&#62;&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>在javascript中，如果要将一个字符串转变成数字，一般是通过parseInt这个函数进行。但如果对输入串有很高确定性的话，其实可以用更简单的方法。如：只是将字符串“123”变成数字123。下面给出具体的说明。</p>
<h2>parseInt函数</h2>
<p>parseInt函数是专门用来处理将字符串变成整型的。具体请见：ECMA-262 P114。</p>
<ol>
<li>支持八进制和十六进制，如：&#8217;0111&#8242;，&#8217;0&#215;111&#8242;。</li>
<li>支持非正数。如：&#8217;-111&#8242;。</li>
<li>支持数字后还有字符串，如：&#8217;111abc&#8217;。</li>
<li>支持第二个参数，是传递的转换进制，数值为2到36。如：parseInt(&#8217;111&#8242;,2)，即将111转换为二进制。</li>
<li>忽略前面的空白字符，如：\n，\t，\r。</li>
<li>如果无法将字符串转换为一个数值，则返回NaN。</li>
</ol>
<p><span id="more-166"></span></p>
<h2>一元操作符“+”</h2>
<p>在javascript中，“+”号即可以作为二元操作符，又可以作为一元操作符。作为一元操作符的时候，就是将对象变成数值形式的。具体见：ECMA-262 P82。</p>
<p>其实执行+的时候，调用JS引擎的ToNumber函数。</p>
<ol>
<li>true/false转成1/0。</li>
<li>null转成0。</li>
<li>支持非正数。</li>
<li>忽略前面的空白字符。</li>
<li>支持16进制，八进制会当十进制处理。</li>
<li>&#8220;111&#8243;转换成111，其他情况基本都是 NaN。</li>
</ol>
<h2>Number构造器</h2>
<p>当number构造器当函数使用时，是将其他对象转化成数值。转换原理跟一元操作符&#8221;+&#8221;完全一样，因为都是调用JS引擎ToNumber函数。所以这个方式基本不用，因为使用它比使用“+”要多7个字符。</p>
<h2>二进制操作符“|”</h2>
<p>使用二进制操作符“|”结合0可以将对象转换成整形的。如&#8217;111&#8242;|0。</p>
<ol>
<li>true/false转换成1/0。</li>
<li>忽略前面的特殊字符。</li>
<li>支持16进制，八进制会当十进制处理。</li>
<li>null转成0。</li>
<li>支持非正数。</li>
<li>不能转换成整型的，则返回为0。如：&#8217;111abc&#8217;结果为0。</li>
</ol>
<h2>二进制操作符“&gt;&gt;”</h2>
<p>使用二进制操作符“&gt;&gt;”结合0可以将对象转换成整形的。如&#8217;111&#8242;&gt;&gt;0。</p>
<ol>
<li>true/false转换成1/0。</li>
<li>忽略前面的特殊字符。</li>
<li>支持16进制，八进制会当十进制处理。</li>
<li>null转成0。</li>
<li>支持非正数。</li>
<li>不能转换成整型的，则返回为0。如：&#8217;111abc&#8217;结果为0。</li>
</ol>
<h2>二进制操作符“&gt;&gt;&gt;”</h2>
<p>使用二进制操作符“&gt;&gt;&gt;”结合0可以将对象转换成整形的。如&#8217;111&#8242;&gt;&gt;&gt;0。</p>
<ol>
<li>true/false转换成1/0。</li>
<li>忽略前面的特殊字符。</li>
<li>支持16进制，八进制会当十进制处理。</li>
<li>null转成0。</li>
<li>非正数的时候则转换为2^32-概数的绝对值。如：&#8217;-111&#8242;&gt;&gt;&gt;0为<span>4294967185</span>。</li>
<li>不能转换成整型的，则返回为0。如：&#8217;111abc&#8217;结果为0。</li>
</ol>
<h2>测试结果</h2>
<p>对于转换的对象数字加字符或者其他类型的，只能用parseInt转换。</p>
<p>对于一般的转化，如将“123”转化成123时，有如下的测试结果：</p>
<table border="1" width="100%">
<tbody>
<tr>
<td></td>
<td>parseInt</td>
<td>+</td>
<td>|</td>
<td>&gt;&gt;</td>
<td>&gt;&gt;&gt;</td>
</tr>
<tr>
<td>IE8(执行10^5次)</td>
<td>96ms</td>
<td>65ms</td>
<td>61ms</td>
<td>59ms</td>
<td>58ms</td>
</tr>
<tr>
<td>FF3.5(执行10^7次)</td>
<td>49ms</td>
<td>48ms</td>
<td>52ms</td>
<td>48ms</td>
<td>53ms</td>
</tr>
<tr>
<td>Safari4(执行10^5次)</td>
<td>38ms</td>
<td>15ms</td>
<td>15ms</td>
<td>15ms</td>
<td>16ms</td>
</tr>
<tr>
<td>Chrome(执行10^5次)</td>
<td>25ms</td>
<td>33ms</td>
<td>37ms</td>
<td>38ms</td>
<td>37ms</td>
</tr>
<tr>
<td>Opera10(执行10^5次)</td>
<td>113ms</td>
<td>61ms</td>
<td>63ms</td>
<td>63ms</td>
<td>66ms</td>
</tr>
</tbody>
</table>
<p>从上面可以看出，除了FF和Chrome下parseInt和其他的没什么差别，其他的使用parseInt函数都要比操作符慢。</p>
<p>所以有时候可以使用“|”操作符来完成字符到数值的转换工作，并且转换默认是0，而不是NaN。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/javascript-toint-method.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript数组唯一化实现方式</title>
		<link>http://www.welefen.com/javascript-array-unique.html</link>
		<comments>http://www.welefen.com/javascript-array-unique.html#comments</comments>
		<pubDate>Mon, 07 Dec 2009 05:10:18 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[unique]]></category>
		<category><![CDATA[唯一化]]></category>
		<category><![CDATA[数组]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=104</guid>
		<description><![CDATA[到目前为止，javascript中array还没有内置的unique方法，本来这篇文章很早就写了，但由于之前的虚拟主机忘记续费导致数据丢了，前几天JerryQu问了我这个问题，觉得可能还有其他人要，这里在写出来，备大家参考。 实现方式 这里给出2中实现方式。一种是大家应该都知道的indexOf检测的方式，另一种是结合lastIndexOf和splice实现方式。 &#19979;&#36733;: array_unique.js//首先给Array对象原型上添加indexOf和lastIndexOf方法.(如果没有的话)if(!Array.prototype.indexOf){&#160;&#160; &#160;Array.prototype.indexOf = function(element, index){&#160;&#160; &#160; &#160; &#160;var length = this.length;&#160;&#160; &#160; &#160; &#160;if(index == null){&#160;&#160; &#160; &#160; &#160; &#160; &#160;index = 0;&#160;&#160; &#160; &#160; &#160;}else{&#160;&#160; &#160; &#160; &#160; &#160; &#160;index = +index &#124;&#124; 0;&#160;&#160; &#160; &#160; &#160; &#160; &#160;if(index &#60; 0) index+= length;&#160;&#160; &#160; &#160; &#160; &#160; &#160;if(index &#60; 0) [...]]]></description>
			<content:encoded><![CDATA[<p>到目前为止，javascript中array还没有内置的unique方法，本来这篇文章很早就写了，但由于之前的虚拟主机忘记续费导致数据丢了，前几天<a href="http://www.qgy18.com/" target="_blank">JerryQu</a>问了我这个问题，觉得可能还有其他人要，这里在写出来，备大家参考。</p>
<h2>实现方式</h2>
<p>这里给出2中实现方式。一种是大家应该都知道的indexOf检测的方式，另一种是结合lastIndexOf和splice实现方式。</p>
<div class="hl-title">&#19979;&#36733;: <a href="http://www.welefen.com/wp-content/plugins/coolcode/coolcode.php?p=104&amp;download=array_unique.js">array_unique.js</a></div><div class="hl-surround"><div class="hl-main"><span style="color: #ffa500;">//首先给Array对象原型上添加indexOf和lastIndexOf方法.(如果没有的话)</span><span style="color: Gray;"><br /></span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">indexOf</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">indexOf</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">element</span><span style="color: Gray;">, </span><span style="color: Blue;">index</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">length</span><span style="color: Gray;"> = </span><span style="color: Green;">this</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">index</span><span style="color: Gray;"> == </span><span style="color: Green;">null</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">index</span><span style="color: Gray;"> = </span><span style="color: Maroon;">0</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Green;">else</span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">index</span><span style="color: Gray;"> = +</span><span style="color: Blue;">index</span><span style="color: Gray;"> || </span><span style="color: Maroon;">0</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">index</span><span style="color: Gray;"> &lt; </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">index</span><span style="color: Gray;">+= </span><span style="color: Blue;">length</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">index</span><span style="color: Gray;"> &lt; </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">index</span><span style="color: Gray;"> = </span><span style="color: Maroon;">0</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">current</span><span style="color: Gray;">;</span><span style="color: Blue;">index</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">length</span><span style="color: Gray;">;</span><span style="color: Blue;">index</span><span style="color: Gray;">++</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">current</span><span style="color: Gray;"> = </span><span style="color: Green;">this</span><span style="color: Olive;">[</span><span style="color: Blue;">index</span><span style="color: Olive;">]</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">current</span><span style="color: Gray;"> === </span><span style="color: Blue;">element</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Blue;">index</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">return</span><span style="color: Gray;"> -</span><span style="color: Maroon;">1</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br /></span><span style="color: Olive;">}</span><span style="color: Gray;"><br /></span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Gray;">!</span><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">lastIndexOf</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Teal;">Array</span><span style="color: Gray;">.</span><span style="color: Blue;">prototype</span><span style="color: Gray;">.</span><span style="color: Blue;">lastIndexOf</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">element</span><span style="color: Gray;">, </span><span style="color: Blue;">index</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">length</span><span style="color: Gray;"> = </span><span style="color: Green;">this</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">index</span><span style="color: Gray;"> == </span><span style="color: Green;">null</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">index</span><span style="color: Gray;"> = </span><span style="color: Blue;">length</span><span style="color: Gray;"> - </span><span style="color: Maroon;">1</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Green;">else</span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">index</span><span style="color: Gray;"> = +</span><span style="color: Blue;">index</span><span style="color: Gray;"> || </span><span style="color: Maroon;">0</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">index</span><span style="color: Gray;"> &lt; </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">index</span><span style="color: Gray;">+= </span><span style="color: Blue;">length</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">index</span><span style="color: Gray;"> &lt; </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">index</span><span style="color: Gray;"> = -</span><span style="color: Maroon;">1</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">else</span><span style="color: Gray;"> </span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">index</span><span style="color: Gray;"> &gt;= </span><span style="color: Blue;">length</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Blue;">index</span><span style="color: Gray;"> = </span><span style="color: Blue;">length</span><span style="color: Gray;"> - </span><span style="color: Maroon;">1</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">current</span><span style="color: Gray;">;</span><span style="color: Blue;">index</span><span style="color: Gray;">&gt;=</span><span style="color: Maroon;">0</span><span style="color: Gray;">;</span><span style="color: Blue;">index</span><span style="color: Gray;">--</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">current</span><span style="color: Gray;"> = </span><span style="color: Green;">this</span><span style="color: Olive;">[</span><span style="color: Blue;">index</span><span style="color: Olive;">]</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">current</span><span style="color: Gray;"> === </span><span style="color: Blue;">element</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Blue;">index</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">return</span><span style="color: Gray;"> -</span><span style="color: Maroon;">1</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br /></span><span style="color: Olive;">}</span><span style="color: Gray;"><br /></span><span style="color: #ffa500;">//很常见的实现方式</span><span style="color: Gray;"><br /></span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">arrayUnique1</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">arr</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">for</span><span style="color: Olive;">(</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;">=</span><span style="color: Maroon;">0</span><span style="color: Gray;">,</span><span style="color: Blue;">len</span><span style="color: Gray;">=</span><span style="color: Blue;">arr</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">,</span><span style="color: Blue;">result</span><span style="color: Gray;">=</span><span style="color: Olive;">[]</span><span style="color: Gray;">,</span><span style="color: Blue;">item</span><span style="color: Gray;">;</span><span style="color: Blue;">i</span><span style="color: Gray;">&lt;</span><span style="color: Blue;">len</span><span style="color: Gray;">;</span><span style="color: Blue;">i</span><span style="color: Gray;">++</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">item</span><span style="color: Gray;"> = </span><span style="color: Blue;">arr</span><span style="color: Olive;">[</span><span style="color: Blue;">i</span><span style="color: Olive;">]</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">result</span><span style="color: Gray;">.</span><span style="color: Blue;">indexOf</span><span style="color: Olive;">(</span><span style="color: Blue;">item</span><span style="color: Olive;">)</span><span style="color: Gray;"> &lt; </span><span style="color: Maroon;">0</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">result</span><span style="color: Olive;">[</span><span style="color: Blue;">result</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Blue;">item</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Blue;">result</span><span style="color: Gray;">;<br /></span><span style="color: Olive;">}</span><span style="color: Gray;"><br /></span><span style="color: #ffa500;">//通过lastIndexOf和splice方法实现方式</span><span style="color: Gray;"><br /></span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">arrayUnique2</span><span style="color: Gray;"> = </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Blue;">arr</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">length</span><span style="color: Gray;"> = </span><span style="color: Blue;">arr</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">while</span><span style="color: Olive;">(</span><span style="color: Gray;">--</span><span style="color: Blue;">length</span><span style="color: Olive;">){</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: #ffa500;">//如果在前面已经出现，则将该位置的元素删除</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Olive;">(</span><span style="color: Blue;">arr</span><span style="color: Gray;">.</span><span style="color: Blue;">lastIndexOf</span><span style="color: Olive;">(</span><span style="color: Blue;">arr</span><span style="color: Olive;">[</span><span style="color: Blue;">length</span><span style="color: Olive;">]</span><span style="color: Gray;">,</span><span style="color: Blue;">length</span><span style="color: Gray;">-</span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;"> &gt; -</span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">arr</span><span style="color: Gray;">.</span><span style="color: Blue;">splice</span><span style="color: Olive;">(</span><span style="color: Blue;">length</span><span style="color: Gray;">,</span><span style="color: Maroon;">1</span><span style="color: Olive;">)</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Blue;">arr</span><span style="color: Gray;">;&nbsp; &nbsp; <br /></span><span style="color: Olive;">}</span></div></div>
<p><span id="more-104"></span></p>
<h2>测试结果</h2>
<p>测试数据：var arr = [1,2,3,1,2,3,2,1,3,4,2,232];<br />
IE7循环10,000次：<br />
arrayUnique1为460ms，arrayUnique2为190ms。<br />
FF3.5循环100,000次：<br />
arrayUnique1为170ms，arrayUnique2为63ms。</p>
<p>从测试结果上可以看出，通过lastIndexOf和splice的方式的速度是普通方式的<font color="red">2-3</font>倍。</p>
<h2>其他实现方式</h2>
<p>除了上面描述的2中实现方式外，其实还是有其他实现方式的。jQuery中就一种实现方式。我们可以看下具体的代码：</p>
<div class="hl-surround"><div class="hl-main"><span style="color: Blue;">unique</span><span style="color: Gray;">: </span><span style="color: Green;">function</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">array</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">ret</span><span style="color: Gray;"> = </span><span style="color: Olive;">[]</span><span style="color: Gray;">, </span><span style="color: Blue;">done</span><span style="color: Gray;"> = </span><span style="color: Olive;">{}</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">try</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">for</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;"> = </span><span style="color: Maroon;">0</span><span style="color: Gray;">, </span><span style="color: Blue;">length</span><span style="color: Gray;"> = </span><span style="color: Blue;">array</span><span style="color: Gray;">.</span><span style="color: Blue;">length</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;"> &lt; </span><span style="color: Blue;">length</span><span style="color: Gray;">; </span><span style="color: Blue;">i</span><span style="color: Gray;">++ </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">var</span><span style="color: Gray;"> </span><span style="color: Blue;">id</span><span style="color: Gray;"> = </span><span style="color: Blue;">jQuery</span><span style="color: Gray;">.</span><span style="color: Blue;">data</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">array</span><span style="color: Olive;">[</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;"> </span><span style="color: Olive;">]</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Green;">if</span><span style="color: Gray;"> </span><span style="color: Olive;">(</span><span style="color: Gray;"> !</span><span style="color: Blue;">done</span><span style="color: Olive;">[</span><span style="color: Gray;"> </span><span style="color: Blue;">id</span><span style="color: Gray;"> </span><span style="color: Olive;">]</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">done</span><span style="color: Olive;">[</span><span style="color: Gray;"> </span><span style="color: Blue;">id</span><span style="color: Gray;"> </span><span style="color: Olive;">]</span><span style="color: Gray;"> = </span><span style="color: Green;">true</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">ret</span><span style="color: Gray;">.</span><span style="color: Blue;">push</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">array</span><span style="color: Olive;">[</span><span style="color: Gray;"> </span><span style="color: Blue;">i</span><span style="color: Gray;"> </span><span style="color: Olive;">]</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"> </span><span style="color: Green;">catch</span><span style="color: Olive;">(</span><span style="color: Gray;"> </span><span style="color: Blue;">e</span><span style="color: Gray;"> </span><span style="color: Olive;">)</span><span style="color: Gray;"> </span><span style="color: Olive;">{</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</span><span style="color: Blue;">ret</span><span style="color: Gray;"> = </span><span style="color: Blue;">array</span><span style="color: Gray;">;<br />&nbsp;&nbsp; &nbsp;</span><span style="color: Olive;">}</span><span style="color: Gray;"><br />&nbsp;&nbsp; &nbsp;</span><span style="color: Green;">return</span><span style="color: Gray;"> </span><span style="color: Blue;">ret</span><span style="color: Gray;">;<br /></span><span style="color: Olive;">}</span></div></div>
<p>这种是通过创建一个临时的对象，然后获取元素的ID保存在对象的key中。<font color="red">但这种实现方式只能针对对象，对于普通的直接量（如：数字，字符串等）是无用的。</font>并且经过测试，这种方式在执行速度上和lastIndexOf结合splice还是有点差距的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/javascript-array-unique.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>javascript中关于try,finally控制语句的使用</title>
		<link>http://www.welefen.com/javascript-try-finally.html</link>
		<comments>http://www.welefen.com/javascript-try-finally.html#comments</comments>
		<pubDate>Mon, 26 Oct 2009 15:17:40 +0000</pubDate>
		<dc:creator>welefen</dc:creator>
				<category><![CDATA[前端开发]]></category>
		<category><![CDATA[finally]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[try]]></category>

		<guid isPermaLink="false">http://www.welefen.com/?p=47</guid>
		<description><![CDATA[几乎每个脚本语言都有try,catch,finally控制语句。try,catch控制语句主要是对有异常的程序控制，这里不在详细描述。主要讲述下try,finally的妙用。 在正文之前，给出2个已有的两个应用（2篇文章都是在51JS中），如下： 1、try finally 妙用,防止内存泄漏。 2、月影发的“某人发给我的邪恶代码”，可以看#16楼 lifesinger的回复。 问题的表面 也许你对上面2个应用还没有真正的明白，也可能你看到这样的代码心里忍不住和我一样惊叹一声“绝”。那么为什么能够写出这样的代码，这样的代码又是怎样工作的呢？一切从ECMA-262开始说起。 揭开面纱 如果你还不知道什么是ECMA-262或者还没有阅读过这个标准，那么我建议你还是尽快花点时间好好看看，有兴趣更要研究。你可以从它的官方网站下载，如果不想看PDF版本的话可以打印出来的。我以前看的时候就是打印出来慢慢研究的。 在ECMA262的12.14 (P70)The try statement有： The production TryStatement : try Block Finally is evaluated as follows: 1. Evaluate Block. 2. Evaluate Finally. 3. If Result(2) .type is normal, return Result(1). 4. Return Result(2). 上述中第一步和第二部分别是计算Block和Finally的值。第三步是进行第二步结果类型的判断，如果类型是normal的话，返回第一步的结果否则返回第二步的结果。 这里有两点比较特殊，一个是返回结果在进行计算Finally块后才进行的，二是第二步的结果类型是normal的时候，返回第一步的结果，否则返回第一步的结果。 对于第一点，前面的防止内存泄露就是一个很好的应用。充分使用了这一特性。 那第二步的结果类型什么时候是normal呢。这里的类型是实现JS引擎层面上的类型，用JS是获取不到的。 JS引擎层面的类型在ECMA262中的8.9进行了定义： 8.9 The Completion Type The internal Completion [...]]]></description>
			<content:encoded><![CDATA[<p>几乎每个脚本语言都有try,catch,finally控制语句。try,catch控制语句主要是对有异常的程序控制，这里不在详细描述。主要讲述下try,finally的妙用。</p>
<p>在正文之前，给出2个已有的两个应用（2篇文章都是在51JS中），如下：</p>
<p>1、<a href="http://bbs.51js.com/viewthread.php?tid=76615" target="_blank"><span>try finally 妙用,防止内存泄漏</span></a>。</p>
<p>2、月影发的“<a href="http://bbs.51js.com/viewthread.php?tid=85823" target="_blank"><span>某人发给我的邪恶代码</span></a>”，可以看#16楼 <a href="http://lifesinger.org/blog/" target="_blank">lifesinger</a>的回复。</p>
<p><span id="more-47"></span></p>
<h2>问题的表面</h2>
<p>也许你对上面2个应用还没有真正的明白，也可能你看到这样的代码心里忍不住和我一样惊叹一声“绝”。那么为什么能够写出这样的代码，这样的代码又是怎样工作的呢？一切从ECMA-262开始说起。</p>
<h2>揭开面纱</h2>
<p>如果你还不知道什么是ECMA-262或者还没有阅读过这个标准，那么我建议你还是尽快花点时间好好看看，有兴趣更要研究。你可以从<a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm" target="_blank">它的官方网站下载</a>，如果不想看PDF版本的话可以打印出来的。我以前看的时候就是打印出来慢慢研究的。</p>
<p>在ECMA262的12.14 (P70)The try statement有：</p>
<blockquote><p>The production TryStatement : try Block Finally is evaluated as follows:<br />
1. Evaluate Block.<br />
2. Evaluate Finally.<br />
3. If Result(2) .type is normal, return Result(1).<br />
4. Return Result(2).</p></blockquote>
<p>上述中第一步和第二部分别是计算Block和Finally的值。第三步是进行第二步结果类型的判断，如果类型是normal的话，返回第一步的结果否则返回第二步的结果。</p>
<p><strong>这里有两点比较特殊，一个是返回结果在进行计算Finally块后才进行的，二是第二步的结果类型是normal的时候，返回第一步的结果，否则返回第一步的结果。</strong></p>
<p>对于第一点，前面的防止内存泄露就是一个很好的应用。充分使用了这一特性。</p>
<p>那第二步的结果类型什么时候是normal呢。这里的类型是实现JS引擎层面上的类型，用JS是获取不到的。</p>
<p>JS引擎层面的类型在ECMA262中的8.9进行了定义：</p>
<blockquote><p>8.9 The Completion Type<br />
The internal Completion type is not a language data type. It is defined by this specification purely for<br />
expository purposes. An implementation of ECMAScript must behave as if it produced and operated upon<br />
Completion values in the manner described here. However, a value of the Completion type is used only as<br />
an intermediate result of statement evaluation and cannot be stored as the value of a variable or property.<br />
The Completion type is used to explain the behaviour of statements (<strong>break, continue, return and throw</strong>) that perform nonlocal transfers of control. Values of the Completion type are triples of the form<br />
(type, value, target), where type is one of normal, break, continue, return, or throw, value is any<br />
ECMAScript value or empty, and target is any ECMAScript identifier or empty.<br />
The term “abrupt completion” refers to any completion with a type other than normal.</p></blockquote>
<p>也就是说，在JS引擎中，有break, continue, return, throw和normal五种完成类型。那么我们就可以知道当finally语句块含有break, continue, return, throw语句被执行时，返回值是第二步的结果，否则为第一步的结果。</p>
<p>上面提到的第二个应用就是基于这一特性的，虽然应用中提到的知识简单的返回结果。但在实际项目中，可以根据这一特性得到不同的返回值。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.welefen.com/javascript-try-finally.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->