<?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>柯南 Become Professional</title>
	<atom:link href="http://www.cloved.cn/feed" rel="self" type="application/rss+xml" />
	<link>http://www.cloved.cn</link>
	<description>贝尔摩得说:天使从来没有对我微笑过</description>
	<lastBuildDate>Tue, 02 Aug 2011 06:13:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>如何给linux添加新硬盘</title>
		<link>http://www.cloved.cn/375.html</link>
		<comments>http://www.cloved.cn/375.html#comments</comments>
		<pubDate>Tue, 02 Aug 2011 06:13:42 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[CnLinux]]></category>
		<category><![CDATA[Command]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ext3]]></category>
		<category><![CDATA[haohaoo]]></category>
		<category><![CDATA[mount dev]]></category>
		<category><![CDATA[partion]]></category>
		<category><![CDATA[partition table]]></category>
		<category><![CDATA[root]]></category>
		<category><![CDATA[siza]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/375.html</guid>
		<description><![CDATA[作者：haohaoo 来自：CnLinux.net工作笔记 转载请保留以上信息，谢谢 在服务器上把硬盘接好，启动linux，以root登陆。 比如我新加一块SCSI硬盘，需要将其分成三个区： #fdisk /dev/sdb 进入fdisk模式： Command (m for help):p&#160; //查看新硬盘的分区 Command (m for help):n&#160; //创建新分区 &#160; 可以用m命令来看fdisk命令的内部命令；n命令创建一个新分区；d命令删除一个存在的分区；p命令显示分区列表；t命令修改分区的类型ID号；l命令显示分区ID号的列表；a命令指定启动分区；w命令是将对分区表的修改存盘让它发生作用。...]]></description>
			<content:encoded><![CDATA[<p>作者：haohaoo    <br />来自：CnLinux.net工作笔记     <br />转载请保留以上信息，谢谢 </p>
<p>在服务器上把硬盘接好，启动linux，以root登陆。 </p>
<p>比如我新加一块SCSI硬盘，需要将其分成三个区： </p>
<p>#fdisk /dev/sdb</p>
<p>进入fdisk模式：</p>
<p>Command (m for help):p&#160; //查看新硬盘的分区</p>
<p>Command (m for help):n&#160; //创建新分区</p>
<p>&#160;</p>
<p>可以用m命令来看fdisk命令的内部命令；n命令创建一个新分区；d命令删除一个存在的分区；p命令显示分区列表；t命令修改分区的类型ID号；l命令显示分区ID号的列表；a命令指定启动分区；w命令是将对分区表的修改存盘让它发生作用。 </p>
<p>&#160;</p>
<p>Command action</p>
<p>&#160;&#160; e&#160;&#160; extended&#160;&#160; //输入e为创建扩展分区</p>
<p>&#160;&#160; p&#160;&#160; primary partition (1-4)&#160;&#160; //输入p为创建主分区，这里我们选择p</p>
<p>&#160;</p>
<p>Partion number(1-4)：1&#160; //第一个扩展分区，按你需求可以最多分4个主分区</p>
<p>First Cylinder(1-1014,default 1):&#160; 1&#160; //第一个主分区起始的磁盘块数</p>
<p>Last cylindet or +siza or +sizeM or +sizeK: +1024MB&#160; //可以是以MB为单位的数字或者以</p>
<p>&#160;</p>
<p>磁盘块数，这里我们输入+1024MB表示分区大小为1G。</p>
<p>&#160;</p>
<p>这样我们就创建完一个分区，如果要创建更多分区可以照上面的步骤继续创建。 </p>
<p>创建完后用w保存分区。 </p>
<p>Command (m for help): w</p>
<p>The partition table has been altered!</p>
<p>&#160;</p>
<p>Calling ioctl() to re-read partition table.</p>
<p>Syncing disks.</p>
<p>这样就分区完，我们还要进行格式化 </p>
<p>#mkfs -t ext3 -c /dev/sdb1&#160; //如果有多个分区，则分区修改为sdb2这样</p>
<p>格式化完后我们需要进行挂载分区， </p>
<p>#mkdir www //创建/www目录，我们将把新的分区挂到www下</p>
<p>#mount /dev/sdb1 /www&#160; //将/dev/sdb1挂载到/www</p>
<p># df&#160; //用df命令进行查看</p>
<p>Filesystem&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1K-blocks&#160;&#160;&#160;&#160;&#160; Used Available Use% Mounted on</p>
<p>/dev/sda2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 3771316&#160;&#160; 1388956&#160;&#160; 2190788&#160; 39% /</p>
<p>/dev/sda1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 101089&#160;&#160;&#160;&#160;&#160; 9463&#160;&#160;&#160;&#160; 86407&#160; 10% /boot</p>
<p>none&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 62988&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0&#160;&#160;&#160;&#160; 62988&#160;&#160; 0% /dev/shm</p>
<p>/dev/sdb1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 485906&#160;&#160;&#160;&#160;&#160; 8239&#160;&#160;&#160; 452580&#160;&#160; 2% /www&#160; //看到了，这就是我们刚</p>
<p>&#160;</p>
<p>才新挂载的分区</p>
<p>&#160;</p>
<p>到这里我们工作已接近尾声了，不过我们如果这样就结束的话，我们每次重新启动服务器后都要 </p>
<p>进行手工挂载，这样很麻烦，我们需要修改/etc/fstab文件来进行自动挂载。 </p>
<p>#vi /etc/fstab</p>
<p>在文件的末尾填加如下内容： </p>
<p>/dev/sdb1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; /www&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ext3&#160;&#160;&#160; defaults&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1 2</p>
<p>如有多个分区可修改sdb1和/www，修改完后保存，重起服务器。 </p>
<p>到此我们添加新硬盘的工作结束了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/375.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>configure: error: no acceptable C compiler found in $PATH</title>
		<link>http://www.cloved.cn/374.html</link>
		<comments>http://www.cloved.cn/374.html#comments</comments>
		<pubDate>Tue, 26 Jul 2011 12:32:53 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[c compiler]]></category>
		<category><![CDATA[development libraries]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[Path]]></category>
		<category><![CDATA[path development]]></category>
		<category><![CDATA[root]]></category>
		<category><![CDATA[station]]></category>
		<category><![CDATA[tools development]]></category>
		<category><![CDATA[x software]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/374.html</guid>
		<description><![CDATA[原因是没装Development Tools和 Development Libraries 安装： [root@station8 ~]# export LANG=en_US.UTF-8 [root@station8 ~]# yum grouplist [root@station8 ~]# yum groupinstall &#34;X Software Development&#34;...]]></description>
			<content:encoded><![CDATA[<p>原因是没装Development Tools和 Development Libraries</p>
<p>安装：</p>
<p>[root@station8 ~]# export LANG=en_US.UTF-8</p>
<p>[root@station8 ~]# yum grouplist</p>
<p>[root@station8 ~]# yum groupinstall &quot;X Software Development&quot;</p>
<p>##安装开发工具和开发库分组：</p>
<p>[root@station8 ~]#yum groupinstall &quot;Development Tools&quot; &quot;Development Libraries&quot;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/374.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sqlite3支持的数据类型 日期函数 Sqlite3 函数</title>
		<link>http://www.cloved.cn/373.html</link>
		<comments>http://www.cloved.cn/373.html#comments</comments>
		<pubDate>Thu, 30 Jun 2011 06:05:12 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[char]]></category>
		<category><![CDATA[count]]></category>
		<category><![CDATA[dd hh]]></category>
		<category><![CDATA[hh mm ss]]></category>
		<category><![CDATA[hour]]></category>
		<category><![CDATA[localtime]]></category>
		<category><![CDATA[smallint]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[sss]]></category>
		<category><![CDATA[varchar]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/373.html</guid>
		<description><![CDATA[Sqlite3支持的数据类型 NULL INTEGER REAL TEXT BLOB 但实际上，sqlite3也接受如下的数据类型： smallint 16 位元的整数。 interger 32 位元的整数。 decimal(p,s) p 精确值和 s 大小的十进位整数，精确值p是指全部有几个数(digits)大小值，s是指小数点後有几位数。如果没有特别指定，则系统会设为 p=5; s=0...]]></description>
			<content:encoded><![CDATA[<p>Sqlite3支持的数据类型   <br /> NULL    <br /> INTEGER    <br /> REAL    <br /> TEXT    <br /> BLOB    <br />但实际上，sqlite3也接受如下的数据类型：    <br /> smallint 16 位元的整数。    <br /> interger 32 位元的整数。    <br /> decimal(p,s) p 精确值和 s 大小的十进位整数，精确值p是指全部有几个数(digits)大小值，s是指小数点後有几位数。如果没有特别指定，则系统会设为 p=5; s=0 。    <br /> float&#160; 32位元的实数。    <br /> double&#160; 64位元的实数。    <br /> char(n)&#160; n 长度的字串，n不能超过 254。    <br /> varchar(n) 长度不固定且其最大长度为 n 的字串，n不能超过 4000。    <br /> graphic(n) 和 char(n) 一样，不过其单位是两个字元 double-bytes， n不能超过127。这个形态是为了支援两个字元长度的字体，例如中文字。    <br /> vargraphic(n) 可变长度且其最大长度为 n 的双字元字串，n不能超过 2000    <br /> date&#160; 包含了 年份、月份、日期。    <br /> time&#160; 包含了 小时、分钟、秒。    <br /> timestamp 包含了 年、月、日、时、分、秒、千分之一秒。</p>
<p>SQLite包含了如下时间/日期函数：   <br />datetime()&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..产生日期和时间    <br />date()&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;产生日期    <br />time()&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;产生时间    <br />strftime()&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..对以上三个函数产生的日期和时间进行格式化    <br />datetime()的用法是：datetime(日期/时间,修正符,修正符&#8230;)    <br />date()和time()的语法与datetime()相同。    <br />在时间/日期函数里可以使用如下格式的字符串作为参数：    <br />YYYY-MM-DD    <br />YYYY-MM-DD HH:MM    <br />YYYY-MM-DD HH:MM:SS    <br />YYYY-MM-DD HH:MM:SS.SSS    <br />HH:MM    <br />HH:MM:SS    <br />HH:MM:SS.SSS    <br />now    <br />其中now是产生现在的时间。    <br />举例（写这个笔记的时间是2006年10月17日晚8点到10点，测试环境：SQLite 2.8.17，WinXP，北京时间）：</p>
<p>例1.   <br />select datetime(&#8216;now&#8217;);    <br />结果：2006-10-17 12:55:54    <br />例2.    <br />select datetime(&#8217;2006-10-17&#8242;);    <br />结果：2006-10-17 12:00:00    <br />例3.    <br />select datetime(&#8217;2006-10-17 00:20:00&#8242;,&#8217;+1 hour&#8217;,'-12 minute&#8217;);    <br />结果：2006-10-17 01:08:00    <br />例4.    <br />select date(&#8217;2006-10-17&#8242;,&#8217;+1 day&#8217;,'+1 year&#8217;);    <br />结果：2007-10-18    <br />例5.    <br />select datetime(&#8216;now&#8217;,'start of year&#8217;);    <br />结果：2006-01-01 00:00:00    <br />例6.    <br />select datetime(&#8216;now&#8217;,'start of month&#8217;);    <br />结果：2006-10-01 00:00:00    <br />例7.    <br />select datetime(&#8216;now&#8217;,'start of day&#8217;);    <br />结果：2006-10-17 00:00:00    <br />例8.    <br />select datetime(&#8216;now&#8217;,'+10 hour&#8217;,'start of day&#8217;,'+10 hour&#8217;);    <br />结果：2006-10-17 10:00:00    <br />例9.    <br />select datetime(&#8216;now&#8217;,'localtime&#8217;);    <br />结果：2006-10-17 21:21:47    <br />例10.    <br />select datetime(&#8216;now&#8217;,'+8 hour&#8217;);    <br />结果：2006-10-17 21:24:45</p>
<p>例3中的+1 hour和-12 minute表示可以在基本时间上（datetime函数的第一个参数）增加或减少一定时间。   <br />例5中的start of year表示一年开始的时间。    <br />从例8可以看出，尽管第2个参数加上了10个小时，但是却被第3个参数“start of day”把时间归零到00:00:00，随后的第4个参数在00:00:00    <br />的基础上把时间增加了10个小时变成了10:00:00。    <br />例9把格林威治时区转换成本地时区。    <br />例10把格林威治时区转换成东八区。    <br />strftime()函数可以把YYYY-MM-DD HH:MM:SS格式的日期字符串转换成其它形式的字符串。    <br />strftime()的语法是strftime(格式, 日期/时间, 修正符, 修正符, &#8230;)    <br />它可以用以下的符号对日期和时间进行格式化：    <br />%d 月份, 01-31    <br />%f 小数形式的秒，SS.SSS    <br />%H 小时, 00-23    <br />%j 算出某一天是该年的第几天，001-366    <br />%m 月份，00-12    <br />%M 分钟, 00-59    <br />%s 从1970年1月1日到现在的秒数    <br />%S 秒, 00-59    <br />%w 星期, 0-6 (0是星期天)    <br />%W 算出某一天属于该年的第几周, 01-53    <br />%Y 年, YYYY    <br />%% 百分号    <br />strftime()的用法举例如下：</p>
<p>例11.   <br />select strftime(&#8216;%Y.%m.%d %H:%M:%S&#8217;,'now&#8217;,'localtime&#8217;);    <br />结果：2006.10.17 21:41:09</p>
<p>函数篇：</p>
<p>算术函数   <br />abs(X) 返回给定数字表达式的绝对值。    <br />max(X,Y[,...]) 返回表达式的最大值。    <br />min(X,Y[,...]) 返回表达式的最小值。    <br />random(*) 返回随机数。    <br />round(X[,Y]) 返回数字表达式并四舍五入为指定的长度或精度。    <br />字符处理函数    <br />length(X) 返回给定字符串表达式的字符个数。    <br />lower(X) 将大写字符数据转换为小写字符数据后返回字符表达式。    <br />upper(X) 返回将小写字符数据转换为大写的字符表达式。    <br />substr(X,Y,Z) 返回表达式的一部分。    <br />randstr()&#160;&#160; <br />quote(A)&#160;&#160; <br />like(A,B) 确定给定的字符串是否与指定的模式匹配。    <br />glob(A,B)&#160;&#160; <br />条件判断函数    <br />coalesce(X,Y[,...])&#160;&#160; <br />ifnull(X,Y)&#160;&#160; <br />nullif(X,Y)&#160;&#160; <br />集合函数    <br />avg(X) 返回组中值的平均值。    <br />count(X) 返回组中项目的数量。    <br />max(X) 返回组中值的最大值。    <br />min(X) 返回组中值的最小值。    <br />sum(X) 返回表达式中所有值的和。    <br />其他函数    <br />typeof(X) 返回数据的类型。    <br />last_insert_rowid() 返回最后插入的数据的ID。    <br />sqlite_version(*) 返回SQLite的版本。    <br />change_count() 返回受上一语句影响的行数。    <br />last_statement_change_count()</p>
<p>&#160;&#160; 管理工具：http://www.sqlitedeveloper.com/&#160;&#160; </p>
<p>&#160;&#160; SQLite ：http://sqlite.phxsoftware.com/&#160; </p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/373.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Schtasks,比at更强的windows计划任务命令</title>
		<link>http://www.cloved.cn/372.html</link>
		<comments>http://www.cloved.cn/372.html#comments</comments>
		<pubDate>Tue, 14 Jun 2011 02:20:19 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/372.html</guid>
		<description><![CDATA[安排命令和程序，使其定期运行或在指定时间运行。向计划中添加和从中删除任务、根据需要启动和停止任务以及显示和更改计划任务。 要查看该命令语法，请单击以下命令： schtasks create 计划任务。 Schtasks 针对各种计划类型使用不同参数组合。要查看创建任务的组合语法或查看创建具有某种计划类型的任务的语法，请单击以下选项之一。 组合语法和参数描述 语法 schtasks /create /sc ScheduleType /tn TaskName /tr TaskRun [/s Computer [/u...]]></description>
			<content:encoded><![CDATA[<p>安排命令和程序，使其定期运行或在指定时间运行。向计划中添加和从中删除任务、根据需要启动和停止任务以及显示和更改计划任务。</p>
<p>要查看该命令语法，请单击以下命令：</p>
<p>schtasks create</p>
<p>计划任务。</p>
<p>Schtasks 针对各种计划类型使用不同参数组合。要查看创建任务的组合语法或查看创建具有某种计划类型的任务的语法，请单击以下选项之一。</p>
<p>组合语法和参数描述</p>
<p>语法   <br />schtasks /create /sc ScheduleType /tn TaskName /tr TaskRun [/s Computer [/u [Domain]User [/p Password]]] [/ru {[Domain]User | System}] [/rp Password] [/mo Modifier] [/d Day[,Day...] | *] [/m Month[,Month...]] [/i IdleTime] [/st StartTime] [/ri Interval] [{/et EndTime | /du Duration} [/k]] [/sd StartDate] [/ed EndDate] [/it] [/Z] [/F]</p>
<p>参数   <br />/sc ScheduleType    <br />指定计划类型。有效值为 MINUTE、HOURLY、DAILY、WEEKLY、MONTHLY、ONCE、ONSTART、ONLOGON、ONIDLE。 计划类型 描述    <br />MINUTE、HOURLY、DAILY、WEEKLY、MONTHLY 指定计划的时间单位。    <br />ONCE 任务在指定的日期和时间运行一次。    <br />ONSTART 任务在每次系统启动的时候运行。可以指定启动的日期，或下一次系统启动的时候运行任务。    <br />ONLOGON 每当用户（任意用户）登录的时候，任务就运行。可以指定日期，或在下次用户登录的时候运行任务。    <br />ONIDLE 只要系统空闲了指定的时间，任务就运行。可以指定日期，或在下次系统空闲的时候运行任务。</p>
<p>/tn TaskName   <br />指定任务的名称。系统上的每项任务都必须具有一个唯一的名称。名称必须符合文件名称规则，并且不得超过 238 个字符。使用引号括起包含空格的名称。    <br />/tr TaskRun    <br />指定任务运行的程序或命令。键入可执行文件、脚本文件或批处理文件的完全合格的路径和文件名。路径名称不得超过 262 个字符。如果忽略该路径，SchTasks 将假定文件在 SystemrootSystem32 目录下。    <br />/s Computer    <br />在指定的远程计算机上计划任务。键入远程计算机的名称或 IP 地址（带有或者没有反斜杠）。该默认值是本地计算机。只有使用 /s 时 /u 和 /p 参数才有效。    <br />/u [Domain]User    <br />使用指定的用户帐户的权限运行该命令。默认值为本地计算机上当前用户的权限。只有在远程计算机 (/s) 上计划任务时 /u 和 /p 参数才有效。    <br />指定帐户的权限用来计划任务和运行任务。要利用另一个用户的权限运行任务，请使用 /ru 参数。</p>
<p>用户帐户必须是远程计算机上 Administrators 组的成员。另外，本地计算机必须与远程计算机处于同一个域，或者必须处于一个远程计算机信任的域中。</p>
<p>/p Password   <br />提供在 /u 参数中指定的用户帐户的密码。如果使用 /u 参数，但忽略 /p 参数或密码参数，Schtasks 将提示您输入密码,并且不显示键入的文本。    <br />只有在远程计算机 (/s) 上计划任务时 /u 和 /p 参数才有效。</p>
<p>/ru {[Domain]User | System}   <br />使用指定用户帐户的权限运行任务。默认情况下，使用本地计算机当前用户的权限，或者使用 /u 参数指定的用户的权限（如果包含的话）运行任务。在本地或远程计算机上计划任务时，/ru 参数才有效。 值 描述</p>
<p>[Domain]User 指定候选用户帐户。   <br />System 或 &quot;&quot; 指定 Local System 帐户，这是一种操作系统和系统服务使用的具有高度特权的帐户。</p>
<p>/rp Password   <br />提供 /ru [Domain]User 参数中指定的用户帐户的密码。如果在指定用户帐户的时候忽略了这个参数，SchTasks.exe 会提示您输入密码而且不显示键入的文本。    <br />不要将 /rp 参数用于使用系统帐户 (/ru System) 的权限运行的任务。系统帐户没有密码，而 SchTasks.exe 也不提示要求密码。</p>
<p>/mo Modifier   <br />指定任务在其计划类型内的运行频率。对于 MINUTE、HOURLY、DAILY、WEEKLY 或 MONTHLY 计划，这个参数有效，但也可选。默认值为 1。 计划类型 修饰符值 描述    <br />MINUTE 1 &#8211; 1439 任务每 N 分钟运行一次。    <br />HOURLY 1 &#8211; 23 任务每 N 小时运行一次。    <br />DAILY 1 &#8211; 365 任务每 N 天运行一次。    <br />WEEKLY 1 &#8211; 52 任务每 N 周运行一次。    <br />ONCE 没有修饰符。 任务运行一次。    <br />ONSTART 没有修饰符。 任务在启动时运行。    <br />ONLOGON 没有修饰符。 /u 参数指定的用户登录时，任务运行。    <br />ONIDLE 没有修饰符。 系统闲置 /i 参数（需要与 ONIDLE 一起使用）指定的分钟数之后运行任务。    <br />MONTHLY 1 &#8211; 12 任务每 N 月运行一次。    <br />MONTHLY LASTDAY 任务在月份的最后一天运行。    <br />MONTHLY FIRST、SECOND、THIRD、FOURTH、LAST 与 /d Day 参数共同使用，并在特定的周和天运行任务。例如，在月份的第三个周三。</p>
<p>/d Day[,Day...] | *   <br />指定周或月的一天（或几天）。只与 WEEKLY 或 MONTHLY 计划共同使用时有效。 计划类型 修饰符 天值 (/d) 描述    <br />WEEKLY 1 &#8211; 52 MON &#8211; SUN[, MON - SUN...]| * 可选项。MON 是默认值。通配符值 (*) 指每天。    <br />MONTHLY FIRST、SECOND、THIRD、FOURTH、LAST MON &#8211; SUN 特定周计划需要。    <br />MONTHLY 无或 {1 &#8211; 12} 1 &#8211; 31 仅在没有修饰符 (/mo) 参数（特定日期计划）的情况下或 /mo 为 1 &#8211; 12（“每 N 月”计划）时有效并且可选。默认值是 1 （月份的第一天）。</p>
<p>/m Month[,Month...]   <br />指定计划任务应在一年的某月或数月运行。有效值是 JAN &#8211; DEC 和 * （每个月）。/m 参数只对于 MONTHLY 计划有效。在使用 LASTDAY 修饰符时，这个参数是必需的。在其他的情况下，它是可选的，默认值是 * （每个月）。    <br />/i IdleTime    <br />指定任务启动之前计算机空闲多少分钟。有效值是从 1 到 999 的整数。这个参数只对于 ONIDLE 计划有效，而且是必需的。    <br />/st StartTime    <br />指定任务在一天的什么时间开始（每次开始时间），格式为 HH:MM 24 小时格式。默认值为本地计算机的当前时间。/st 参数只对于 MINUTE、HOURLY、DAILY、WEEKLY、MONTHLY 和 ONCE 计划有效。此参数对于 ONCE 计划是必需的。    <br />/ri Interval    <br />指定重复的时间间隔（以分钟计）。这不适用于计划类型：MINUTE、HOURLY、ONSTART、ONLOGON、ONIDLE。有效范围为 1 到 599940 分钟（599940 分钟 = 9999 小时）。如果指定了 /ET 或 /DU，则重复间隔默认为 10 分钟。    <br />/et EndTime    <br />指定“分钟”或“小时”任务计划在一天的什么时间结束，格式为 HH:MM 24 小时格式。指定的结束时间之后，Schtasks 不重新开始任务，直到开始时间再次到来。默认情况下，任务计划没有结束时间。该参数是可选的，并且仅对于“分钟”或“小时”计划才有效。    <br />要查看示例，请参阅：</p>
<p>“计划任务每 n 分钟运行一次”部分的“计划任务在非工作时间内每 100 分钟运行一次”。   <br />/du Duration    <br />指定“分钟”或“小时”计划的最大时间长度，格式为 HHHH:MM 24 小时格式。指定的时间过去之后，Schtasks 不重新启动任务，直到开始时间再次到来。默认情况下，任务计划没有最大持续时间。该参数是可选的，并且仅对于“分钟”或“小时”计划才有效。    <br />要查看示例，请参阅：</p>
<p>“计划任务每 N 小时运行一次”部分的“计划每 3 小时运行一次、持续时间为 10 小时的任务”。   <br />/k    <br />停止在 /et 或 /du 指定的时间运行任务的程序。如果没有 /k，Schtasks 在到达 /et 或 /du 指定的时间之后就不重新启动程序，但不会停止仍然在运行的程序。该参数是可选的，并且仅对于“分钟”或“小时”计划才有效。    <br />要查看示例，请参阅：</p>
<p>“计划任务每 N 分钟运行一次”部分的“计划任务在非工作时间内每 100 分钟运行一次”。   <br />/sd StartDate    <br />指定任务计划开始的日期。默认值为本地计算机上的当前日期。/sd 对于所有计划类型有效，并且为可选。    <br />StartDate 参数的格式随在“控制面板”中的 区域和语言选项中为本地计算机选择的区域而变化。每个区域只能使用一种格式。</p>
<p>下表列出了有效的日期格式。使用与本地计算机控制面板的“区域和语言选项”中为“短日期”所选格式最为相似的格式。</p>
<p>MM/DD/YYYY 用于以月开头的格式，例如英语（美国）和西班牙语（巴拿马）。   <br />DD/MM/YYYY 用于以日开头的格式，例如保加利亚语和荷兰语（荷兰）。    <br />YYYY/MM/DD 用于以年开头的格式，例如瑞典语和法语（加拿大）。</p>
<p>/ed EndDate   <br />指定计划结束的日期。此参数是可选的。它对于 ONCE、ONSTART、ONLOGON 或 ONIDLE 计划无效。默认情况下，计划没有结束日期。    <br />EndDate 参数的格式随在“控制面板”中的 区域和语言选项中为本地计算机选择的区域的不同而变化。每个区域只能使用一种格式。</p>
<p>下表列出了有效的日期格式。使用与本地计算机控制面板的“区域和语言选项”中为“短日期”所选格式最为相似的格式。</p>
<p>MM/DD/YYYY 用于以月开头的格式，例如英语（美国）和西班牙语（巴拿马）。   <br />DD/MM/YYYY 用于以日开头的格式，例如保加利亚语和荷兰语（荷兰）。    <br />YYYY/MM/DD 用于以年开头的格式，例如瑞典语和法语（加拿大）。</p>
<p>/it   <br />指定只有在“运行方式”用户（运行任务的用户帐户）登录到计算机的情况下才运行任务。此参数不影响使用系统权限运行的任务。    <br />默认情况下，当计划任务时或使用 /u 参数指定帐户时，“运行方式”用户是本地计算机的当前用户（如果使用了该参数）。但是，如果该命令包含 /ru 参数，“运行方式”用户则是由 /ru 参数指定的帐户。</p>
<p>例如，请参阅：</p>
<p>“计划任务每 N 天运行一次”部分的“计划在我登录时每 70 天运行一次任务”。   <br />“计划使用不同权限运行的任务”部分的“只在特定用户登录时运行任务”。    <br />/Z    <br />指定在任务计划完成时删除任务。    <br />/F    <br />指定如果指定任务已经存在，就创建任务并取消警告。    <br />/?    <br />在命令提示符下显示帮助。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/372.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL 数据库引入 memcached，支持 NoSQL</title>
		<link>http://www.cloved.cn/369.html</link>
		<comments>http://www.cloved.cn/369.html#comments</comments>
		<pubDate>Sat, 23 Apr 2011 02:32:35 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[expo]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[key value]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/?p=369</guid>
		<description><![CDATA[Oracle 前天在 2011 MySQL user conference and expo 大会上发布的 MySQL 5.6.2 测试版本，详情请看这里。 该版本最值得关注的便是对 NoSQL 技术的支持，尽管目前还是实验阶段，该技术使得 MySQL 内置 NoSQL 技术，该技术可减少 memcached 的查询延迟。在单台机器中，NoSQL 当前只适用一张...]]></description>
			<content:encoded><![CDATA[<p>Oracle 前天在 <strong>2011 MySQL user conference and expo</strong> 大会上发布的 MySQL 5.6.2 测试版本，详情请看<a href="http://www.oschina.net/news/17118/mysql-5-6-2-dev">这里</a>。</p>
<p>该版本最值得关注的便是对 NoSQL 技术的支持，尽管目前还是实验阶段，该技术使得 MySQL 内置 NoSQL 技术，该技术可减少 <a href="http://www.oschina.net/p/memcached">memcached</a> 的查询延迟。在单台机器中，NoSQL 当前只适用一张 InnoDB 表，但未来将支持多个表。在 memcached 中的 key 和 value 分别对应表中的相应字段，同时可为 key 定义多列的值。所有这些数据都存储在一张 InnoDB 表，可通过 SQL 命令来进行检索和修改。目前集成 memcached 守护进程的版本只能用于 Linux。</p>
<p>来自 InnoDB 的<a href="http://blogs.innodb.com/wp/2011/04/get-started-with-innodb-memcached-daemon-plugin/" target="_blank">博客</a>向你介绍如何启用该功能</p>
<p>下图是该技术的架构图</p>
<p><img src="http://static.oschina.net/uploads/space/2011/0413/092813_o0JD_12.jpg" alt="" /></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/369.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>uafxcwd.lib LIBCMTD.lib 弱外部链接(ZT)</title>
		<link>http://www.cloved.cn/366.html</link>
		<comments>http://www.cloved.cn/366.html#comments</comments>
		<pubDate>Mon, 18 Apr 2011 05:13:23 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[Twitter]]></category>
		<category><![CDATA[CRT]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[lib]]></category>
		<category><![CDATA[LNK]]></category>
		<category><![CDATA[microsoft mfc]]></category>
		<category><![CDATA[specific library]]></category>
		<category><![CDATA[uafxcwd]]></category>
		<category><![CDATA[unsigned int]]></category>
		<category><![CDATA[void]]></category>
		<category><![CDATA[vs2005]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/?p=366</guid>
		<description><![CDATA[今天debug一程序 出现如下错误： uafxcwd.lib(afxmem.obj) : error LNK2005: &#8220;void * __cdecl operator new(unsigned int)&#8221; (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj) uafxcwd.lib(afxmem.obj) : error...]]></description>
			<content:encoded><![CDATA[<p>今天debug一程序 出现如下错误：</p>
<p>uafxcwd.lib(afxmem.obj) : error LNK2005: &#8220;void * __cdecl operator new(unsigned int)&#8221; (??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)<br />
uafxcwd.lib(afxmem.obj) : error LNK2005: &#8220;void __cdecl operator delete(void *)&#8221; (??3@YAXPAX@Z) already defined in LIBCMTD.lib(dbgdel.obj)<br />
uafxcwd.lib(afxmem.obj) : error LNK2005: &#8220;void __cdecl operator delete[](void *)&#8221; (??_V@YAXPAX@Z) already defined in LIBCMTD.lib(delete2.obj)</p>
<p>原因：</p>
<p>CRT 库对 new、delete 和 DllMain 函数使用弱外部链接。MFC 库也包含 new、delete 和 DllMain 函数。这些函数要求先链接 MFC 库，然后再链接 CRT 库。</p>
<p>当 C 运行时 (CRT) 库和 Microsoft 基础类 (MFC) 库的链接顺序有误时，可能会出现以下 LNK2005 错误。</p>
<p>解决方法：</p>
<p>强制链接器按照正确的顺序链接库！</p>
<p>project->properties->Linker->Ignore Specific Library 添加 uafxcwd.lib Libcmtd.lib</p>
<p>在Additional Dependencied添加uafxcwd.lib Libcmtd.lib</p>
<p>问题解决！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/366.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>开源搜索引擎资源</title>
		<link>http://www.cloved.cn/363.html</link>
		<comments>http://www.cloved.cn/363.html#comments</comments>
		<pubDate>Sat, 09 Apr 2011 06:43:24 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[java lucene]]></category>
		<category><![CDATA[leo galambos]]></category>
		<category><![CDATA[Lucene]]></category>
		<category><![CDATA[nutch]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[powerpoing]]></category>
		<category><![CDATA[RTF]]></category>
		<category><![CDATA[xml html]]></category>
		<category><![CDATA[YaCy]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/?p=363</guid>
		<description><![CDATA[开放源代码搜索引擎为人们学习、研究并掌握搜索技术提供了极好的途径与素材，推动了搜索技术的普及与发展，使越来越多的人开始了解并推广使用搜索技术。使用开源搜索引擎，可以大大缩短构建搜索应用的周期，并可根据应用需求打造个性化搜索应用，甚至构建符合特定需求的搜索引擎系统。搜索引擎的开源，无论是对技术人员还是普通用户，都是一个福音。 搜索引擎的工作流程主要分为三步：从互联网抓取网页→创建抓取网页的索引库→从索引库中进行搜索。 首先需要一个能访问网络的爬虫器程序，依据URL之间的关联性自动爬行整个互联网，并对爬行过的网页进行抓取收集。当网页被收集回来后，采用索引分析程序进行网页信息的分析，依据一定的相关度算法（如超链接算法）进行大量计算，创建倒排序的索引库。索引库建好后用户就可以通过提供的搜索界面提交关键词进行搜索，依据特定的排序算法返回搜索结果。因此，搜索引擎并不是对互联网进行直接搜索，而是对已抓取网页索引库的搜索，这也是能快速返回搜索结果的原因，索引在其中扮演了最为重要的角色，索引算法的效率直接影响搜索引擎的效率，是评测搜索引擎是否高效的关键因素。 网页爬行器、索引器、查询器共同构成了搜索引擎的重要组成单元，针对特定的语言，如中文、韩文等，还需要分词器进行分词，一般情况下，分词器与索引器一起使用创建特定语言的索引库。它们之间的协同关系如图1所示。 而开放源代码的搜索引擎为用户提供了极大的透明性，开放的源代码、公开的排序算法、随意的可定制性，相比于商业搜索引擎而言，更为用户所需要。目前，开放源代码的搜索引擎项目也有一些，主要集在中搜索引擎开发工具包与架构、Web搜索引擎、文件搜索引擎几个方面，本文概要介绍一下当前比较流行且相对比较成熟的几个搜索引擎项目。 开源搜索引擎工具包 1．Lucene Lucene是目前最为流行的开放源代码全文搜索引擎工具包，隶属于Apache基金会，由资深全文索引/检索专家Doug Cutting所发起，并以其妻子的中间名作为项目的名称。Lucene不是一个具有完整特征的搜索应用程序，而是一个专注于文本索引和搜索的工具包，能够为应用程序添加索引与搜索能力。基于Lucene在索引及搜索方面的优秀表现，虽然由Java编写的Lucene具有天生的跨平台性，但仍被改编为许多其他语言的版本：Perl、Python、C++、.Net等。 (关于Lucene的详细介绍请参考http://www.chedong.com/tech/lucene.html) 同其他开源项目一样，Lucene具有非常好的架构，能够方便地在其基础上进行研究与开发，添加新功能或者开发新系统。Lucene本身只支持文本文件及少量语种的索引，并且不具备爬虫功能，而这正是Lucene的魅力所在，通过Lucene提供的丰富接口，我们可以根据自身的需要在其上添加具体语言的分词器，针对具体文档的文本解析器等，而这些具体的功能实现都可以借助于一些已有的相关开源软件项目、甚至是商业软件来完成，这也保证了Lucene在索引及搜索方面的专注性。目前，通过在Lucene的基础上加入爬行器、文本解析器等也形成了一些新的开源项目，如LIUS、Nutch等。并且Lucene的索引数据结构已经成了一种事实上的标准，为许多搜索引擎所采用。 2．LIUS LIUS即Lucene Index Update and Search的缩写，它是以Lucene为基础发展起来的一种文本索引框架，和Lucene一样，同样可以看作搜索引擎开发工具包。它在Lucene的基础上作了一些相应的研究及添加了一些新的功能。LIUS借助于许多开源软件，可以直接对各种不同格式/类型的文档进行文本解析与索引，这些文档格式包括MS Word、MS Excel、MS PowerPoing、RTF、PDF、XML、HTML、TXT、Open...]]></description>
			<content:encoded><![CDATA[<p><span style="color: #008000;">开放源代码搜索引擎</span>为人们学习、研究并掌握搜索技术提供了极好的途径与素材，推动了搜索技术的普及与发展，使越来越多的人开始了解并推广使用搜索技术。使用<strong>开源搜索引擎</strong>，可以大大缩短构建搜索应用的周期，并可根据应用需求打造个性化搜索应用，甚至构建符合特定需求的搜索引擎系统。搜索引擎的开源，无论是对技术人员还是普通用户，都是一个福音。<br />
<a href="http://www.kankanblog.com/tag.php?tag=%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E" target="_blank">搜索引擎</a>的工作流程主要分为三步：从互联网抓取网页→创建抓取网页的索引库→从索引库中进行搜索。</p>
<p>首先需要一个能访问网络的爬虫器程序，依据URL之间的关联性自动爬行整个互联网，并对爬行过的网页进行抓取收集。当网页被收集回来后，采用索引分析程序进行网页信息的分析，依据一定的<strong>相关度算法</strong>（如超链接算法）进行大量计算，创建倒排序的<strong>索引库</strong>。索引库建好后用户就可以通过提供的搜索界面提交关键词进行搜索，依据特定的排序算法返回搜索结果。因此，<strong>搜索引擎并不是对互联网进行直接搜索，而是对已抓取网页索引库的搜索</strong>，这也是能快速返回搜索结果的原因，<strong>索引在其中扮演了最为重要的角色</strong>，索引算法的效率直接影响搜索引擎的效率，是评测搜索引擎是否高效的关键因素。</p>
<p>网页爬行器、索引器、查询器共同构成了搜索引擎的重要组成单元，针对特定的语言，如中文、韩文等，还需要分词器进行分词，一般情况下，分词器与索引器一起使用创建特定语言的索引库。它们之间的协同关系如图1所示。</p>
<p>而开放源代码的搜索引擎为用户提供了极大的透明性，开放的源代码、公开的<strong>排序算法</strong>、随意的可定制性，相比于<a href="http://www.kankanblog.com/tag.php?tag=google" target="_blank">商业搜索引擎</a>而言，更为用户所需要。目前，开放源代码的搜索引擎项目也有一些，主要集在中搜索引擎开发工具包与架构、Web搜索引擎、文件搜索引擎几个方面，本文概要介绍一下当前比较流行且相对比较成熟的几个搜索引擎项目。</p>
<p><strong>开源搜索引擎工具包</strong></p>
<p>1．Lucene<br />
Lucene是目前最为流行的开放源代码<strong>全文</strong>搜索引擎工具包，隶属于<a href="http://www.apache.org/" target="_blank">Apache基金会</a>，由资深全文索引/检索专家Doug Cutting所发起，并以其妻子的中间名作为项目的名称。Lucene不是一个具有完整特征的搜索应用程序，而是一个专注于文本索引和搜索的工具包，能够为应用程序添加索引与搜索能力。基于Lucene在索引及搜索方面的优秀表现，虽然由Java编写的Lucene具有天生的跨平台性，但仍被改编为许多其他语言的版本：Perl、Python、C++、.Net等。 (关于Lucene的详细介绍请参考<a href="http://www.chedong.com/tech/lucene.html" target="_blank">http://www.chedong.com/tech/lucene.html</a>)<br />
同其他开源项目一样，Lucene具有非常好的架构，能够方便地在其基础上进行研究与开发，添加新功能或者开发新系统。Lucene本身只支持文本文件及少量语种的索引，并且不具备爬虫功能，而这正是Lucene的魅力所在，通过Lucene提供的丰富接口，我们可以根据自身的需要在其上添加具体语言的分词器，针对具体文档的文本解析器等，而这些具体的功能实现都可以借助于一些已有的相关开源软件项目、甚至是商业软件来完成，这也保证了Lucene在索引及搜索方面的专注性。目前，通过在Lucene的基础上加入爬行器、文本解析器等也形成了一些新的开源项目，如LIUS、Nutch等。并且Lucene的<strong>索引数据结构</strong>已经成了一种事实上的标准，为许多搜索引擎所采用。</p>
<p>2．LIUS<br />
LIUS即Lucene Index Update and Search的缩写，它是以Lucene为基础发展起来的一种文本索引框架，和Lucene一样，同样可以看作搜索引擎开发工具包。它在Lucene的基础上作了一些相应的研究及添加了一些新的功能。LIUS借助于许多开源软件，可以直接对各种不同格式/类型的文档进行文本解析与索引，这些文档格式包括MS Word、MS Excel、MS PowerPoing、RTF、PDF、XML、HTML、TXT、Open Office及JavaBeans等，对<strong>Java Beans</strong>的支持对于进行数据库索引非常有用，在用户进行对象关系映射（如：Hibernate、JDO、TopLink、Torque等）的数据库连接编程时会变得更加精确。LIUS还在Lucene的基础上增加了索引更新功能，使针对索引的维护功能进一步完善。并且支持混和索引，可以把同一目录下与某一条件相关的所有内容整合到一起，这种功能对于需要对多种不同格式的文档同时进行索引时非常有用。</p>
<p>3．Egothor<br />
Egothor是一款开源的高性能全文搜索引擎，适用于基于全文搜索功能的搜索应用，它具有与Luccene类似的<strong>核心算法</strong>，这个项目已经存在了很多年，并且拥有一些积极的开发人员及用户团体。项目发起者Leo Galambos是捷克布拉格查理大学数学与物理学院的一名高级助理教授，他在博士研究生期间发起了此项目。<br />
更多的时候，我们把Egothor看作一个用于全文搜索引擎的Java库，能够为具体的应用程序添加全文搜索功能。它提供了扩展的Boolean模块，使得它能被作为Boolean模块或者Vector模块使用，并且Egothor具有一些其他搜索引擎所不具有的特有功能：它采用新的<strong>动态算法</strong>以有效提高索引更新的速度，并且支持平行的查询方式，可有效提高查询效率。在Egothor的发行版中，加入了爬行器、文本解析器等许多增强易用性的应用程序，融入了Golomb、Elias-Gamma等多种高效的压缩方法，支持多种常用文档格式的文本解析，如HTML、PDF、PS、微软Office文档、XLS等，提供了GUI的索引界面及基于Applet或者Web的查询方式。另外，Egothor还能被方便地配置成独立的搜索引擎、元数据搜索器、点对点的HUB等多种且体的应用系统。</p>
<p>4．Xapian<br />
Xapian是基于GPL发布的搜索引擎开发库，它采用C++语言编写，通过其提供绑定程序包可以使Perl、Python、PHP、Java、Tck、C#、Ruby等语言方便地使用它。<br />
Xapian还是一个具有高适应性的工具集，使开发人员能够方便地为他们的应用程序添加高级索引及搜索功能。它支持信息检索的概率模型及丰富的布尔查询操作。Xapian的发布包通常由两部分组成：xapian-core及xapian-bindings，前者是核心主程序，后者是与其他语言进行绑定的程序包。<br />
Xapian为程序开发者提供了丰富的API及文档进行程序的编制，而且还提供了许多编程实例及一个基于Xapian的应用程序Omega，Omega 由索引器及基于CGI的前端搜索组成，能够为HTML、PHP、PDF、PostScript、OpenOffice/StarOffice、RTF等多 种格式的文档编制索引，通过使用Perl DBI模块甚至能为MySQL、PostgreSQL、SQLite、Sybase、MS SQL、LDAP、ODBC等关系数据库编制索引，并能以CSV或XML格式从前端导出搜索结果，程序开发者可以在此基础上进行扩展。</p>
<p>5．Compass<br />
Compass是在Lucene上实现的开源搜索引擎架构，相对比于Lucene而言，提供更加简洁的搜索引擎API。增加了索引事务处理的支持，使其能够更方便地与数据库等事务处理应用进行整合。它更新时无需删除原文档，更加简单更加高效。资源与搜索引擎之间采用映射机制，此种机制使得那些已经使用了Lucene或者不支持对象及XML的应用程序迁移到Compass上进行开发变得非常容易。<br />
Compass还能与Hibernate、Spring等架构进行集成，因此如果想在Hibernate、Spring项目中加入搜索引擎功能，Compass是个极好的选择。</p>
<p><strong>开源Web搜索引擎系统 </strong></p>
<p>1．Nutch<br />
Nutch是Lucene的作者Doug Cutting发起的另一个开源项目，它是构建于Lucene基础上的完整的Web搜索引擎系统，虽然诞生时间不长，但却以其优良血统及简洁方便的使用方式而广收欢迎。我们可以使用Nutch搭建类似<a href="http://www.google.com/" target="_blank">Google</a>的完整的搜索引擎系统，进行局域网、互联网的搜索。<br />
2．YaCy<br />
YaCy是一款基于P2P(peer-to-peer)的分布式开源Web搜索引擎系统，采用Java语言进行编写，其核心是分布在数百台计算机上的被称为YaCy-peer的计算机程序， 基于P2P网络构成了YaCy网络，整个网络是一个分散的架构，在其中所有的YaCy-peers都处于对等的地位，没有统一的中心服务器，每个YaCy -peer都能独立的进行互联网的爬行抓取、分析及创建索引库，通过P2P网络与其他YaCy-peers进行共享，并且每个YaCy-peer又都是一 个独立的代理服务器，能够对本机用户使用过的网页进行索引，并且采取多机制来保护用户的隐私，同时用户也通过本机运行的Web服务器进行查询及返回查询结 果。<br />
YaCy搜索引擎主要包括五个部分，除普通搜索引擎所具有的爬行器、索引器、反排序的索引库外，它还包括了一个非常丰富的搜索与管理界面以及用于数据共享的P2P网络。</p>
<p><strong>开源桌面搜索引擎系统 </strong></p>
<p>1．Regain<br />
regain是一款与Web搜索引擎类似的桌面搜索引擎系统，其不同之处在于regain不是对Internet内容的搜索，而是针对自己的文档或文件的搜索，使用regain可以轻松地在几秒内完成大量数据（许多个G）的搜索。Regain采用了Lucene的搜索语法，因此支持多种查询方式，支持多索引的搜索及基于文件类型的高级搜索，并且能实现URL重写及文件到HTTP的桥接，并且对中文也提供了较好的支持。<br />
Regain提供了两种版本：桌面搜索及服务器搜索。桌面搜索提供了对普通桌面计算机的文档与局域网环境下的网页的快速搜索。服务器版本主要安装在Web服务器上，为网站及局域网环境下的文件服务器进行搜索。<br />
Regain使用Java编写，因此可以实现跨平台安装，能安装于Windows、Linux、Mac OS及Solaris上。服务器版本需要JSPs环境及标签库（tag library），因此需要安装一个<a href="http://tomcat.apache.org/" target="_blank">Tomcat容器</a>。而桌面版自带了一个小型的Web服务器，安装非常简单。</p>
<p>2．Zilverline<br />
Zilverline是一款以Lucene为基础的桌面搜索引擎，采用了Spring框架，它主要用于个人本地磁盘及局域网内容的搜索， 支持多种语言。Zilverline提供了丰富的文档格式的索引支持，如微软Office文档、RTF、Java、CHM等，甚至能够为归档文件编制索引 进行搜索，如zip、rar及其他归档文件，在索引过程中，Zilverline从zip、rar、chm等归档文件中抽取文件来编制索引。 Zilverline可以支持<strong>增量索引</strong>的方式，只对新文件编制索引，同时也支持定期自动索引，其索引库能被存放于Zilverline能够访问到的地方，甚至是DVD中。同时，Zilverline还支持文件路径到URL的映射，这样可以使用户远程搜索本地文件。<br />
Zilverline提供了个人及研究、商业应用两种许可方式，其发布形式为一个简单的<strong>war包</strong>，可以从其官方网站下载（<a href="http://www.zilverline.org/" target="_blank">http://www.zilverline.org/</a>）。 Zilverline的运行环境需要Java环境及Servlet容器，一般使用Tomcat即可。在确保正确安装JDK及Tomcat容器后只需将 Zilverline的war包（zilverline-1.5.0.war）拷贝到Tomcat的webapps目录后重启Tomcat容器即可开始使 用Zilverline搜索引擎了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/363.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>临界区，互斥量，信号量，事件的区别</title>
		<link>http://www.cloved.cn/359.html</link>
		<comments>http://www.cloved.cn/359.html#comments</comments>
		<pubDate>Fri, 18 Mar 2011 13:43:33 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[BOOL]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[CCriticalSection]]></category>
		<category><![CDATA[createmutex]]></category>
		<category><![CDATA[critical section]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[Lock]]></category>
		<category><![CDATA[lpctstr]]></category>
		<category><![CDATA[NULL]]></category>
		<category><![CDATA[pv]]></category>
		<category><![CDATA[WaitForSingleObject]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/?p=359</guid>
		<description><![CDATA[四种进程或线程同步互斥的控制方法 1、临界区:通过对多线程的串行化来访问公共资源或一段代码，速度快，适合控制数据访问。 2、互斥量:为协调共同对一个共享资源的单独访问而设计的。 3、信号量:为控制一个具有有限数量用户资源而设计。 4、事 件:用来通知线程有一些事件已发生，从而启动后继任务的开始。 临界区（Critical Section） 保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区，那么在有一个线 程进入后其他所有试图访问此临界区的线程将被挂起，并一直持续到进入临界区的线程离开。临界区在被释放后，其他线程可以继续抢占，并以此达到用原子方式操 作共享资源的目的。 临界区包含两个操作原语： EnterCriticalSection（） 进入临界区 LeaveCriticalSection（） 离开临界区 EnterCriticalSection（）语句执行后代码将进入临界区以后无论发生什么，必须确保与之匹配的 LeaveCriticalSection（）都能够被执行到。否则临界区保护的共享资源将永远不会被释放。虽然临界区同步速度很快，但却只能用来同步本 进程内的线程，而不可用来同步多个进程中的线程。 MFC提供了很多功能完备的类，我用MFC实现了临界区。MFC为临界区提供有一个CCriticalSection类，使用该类进行线程同步处理是...]]></description>
			<content:encoded><![CDATA[<p><strong>四种进程或线程同步互斥的控制方法</strong><br />
<strong> 1、临界区:通过对多线程的串行化来访问公共资源或一段代码，速度快，适合控制数据访问。</strong><br />
<strong> 2、互斥量:为协调共同对一个共享资源的单独访问而设计的。</strong><br />
<strong> 3、信号量:为控制一个具有有限数量用户资源而设计。</strong><br />
<strong> 4、事 件:用来通知线程有一些事件已发生，从而启动后继任务的开始</strong>。</p>
<p><span style="color: #ff0000;">临界区（Critical Section）</span></p>
<p>保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区，那么在有一个线 程进入后其他所有试图访问此临界区的线程将被挂起，并一直持续到进入临界区的线程离开。临界区在被释放后，其他线程可以继续抢占，并以此达到用原子方式操 作共享资源的目的。<br />
临界区包含两个操作原语：</p>

<div class="wp_codebox"><table><tr id="p3595"><td class="code" id="p359code5"><pre class="cpp" style="font-family:monospace;">EnterCriticalSection（） 进入临界区
LeaveCriticalSection（） 离开临界区</pre></td></tr></table></div>

<p>EnterCriticalSection（）语句执行后代码将进入临界区以后无论发生什么，必须确保与之匹配的 LeaveCriticalSection（）都能够被执行到。否则临界区保护的共享资源将永远不会被释放。虽然临界区同步速度很快，但却只能用来同步本 进程内的线程，而不可用来同步多个进程中的线程。<br />
MFC提供了很多功能完备的类，我用MFC实现了临界区。MFC为临界区提供有一个CCriticalSection类，使用该类进行线程同步处理是 非常简单的。只需在线程函数中用CCriticalSection类成员函数Lock（）和UnLock（）标定出被保护代码片段即可。Lock（）后代 码用到的资源自动被视为临界区内的资源被保护。UnLock后别的线程才能访问这些资源。</p>
<p><span style="color: #ff0000;">互斥量（Mutex）</span></p>
<p>互斥量跟临界区很相似，只有拥有互斥对象的线程才具有访问资源的权限，由于互斥对象只有一个，因此就决定了任何情况下此共享资源都不会同时被多个线程 所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出，以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同 一应用程序不同线程中实现资源的安全共享，而且可以在不同应用程序的线程之间实现对资源的安全共享。</p>
<p>互斥量包含的几个操作原语：</p>

<div class="wp_codebox"><table><tr id="p3596"><td class="code" id="p359code6"><pre class="cpp" style="font-family:monospace;">CreateMutex（） 创建一个互斥量
OpenMutex（） 打开一个互斥量
ReleaseMutex（） 释放互斥量
WaitForMultipleObjects（） 等待互斥量对象</pre></td></tr></table></div>

<p>同样MFC为互斥量提供有一个CMutex类。使用CMutex类实现互斥量操作非常简单，但是要特别注意对CMutex的构造函数的调用<br />
CMutex( BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL)<br />
不用的参数不能乱填，乱填会出现一些意想不到的运行结果。</p>
<p><span style="color: #ff0000;">信号量（Semaphores）</span></p>
<p>信号量对象对线程的同步方式与前面几种方法不同，信号允许多个线程同时使用共享资源，这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程 最大数目。它允许多个线程在同一时刻访问同一资源，但是需要限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore（）创建信号量 时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数，每增加一个线程对共享资源的访问，当前可用资源计数 就会减1，只要当前可用资源计数是大于0的，就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目， 不能在允许其他线程的进入，此时的信号量信号将无法发出。线程在处理完共享资源后，应在离开的同时通过ReleaseSemaphore（）函数将当前可 用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。<br />
PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数，S大于等于零时代表可供并发进程使用的资源实体数，但S小于零时则表示正在等待使用共享资源的进程数。<br />
P操作 申请资源：<br />
（1）S减1；<br />
（2）若S减1后仍大于等于零，则进程继续执行；<br />
（3）若S减1后小于零，则该进程被阻塞后进入与该信号相对应的队列中，然后转入进程调度。<br />
V操作 释放资源：<br />
（1）S加1；<br />
（2）若相加结果大于零，则进程继续执行；<br />
（3）若相加结果小于等于零，则从该信号的等待队列中唤醒一个等待进程，然后再返回原进程继续执行或转入进程调度。</p>
<p>信号量包含的几个操作原语：</p>

<div class="wp_codebox"><table><tr id="p3597"><td class="code" id="p359code7"><pre class="cpp" style="font-family:monospace;">   　　CreateSemaphore（） 创建一个信号量
   　　OpenSemaphore（） 打开一个信号量
   　　ReleaseSemaphore（） 释放信号量
   　　WaitForSingleObject（） 等待信号量</pre></td></tr></table></div>

<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal; color: #ff0000;">事件（Event）</span><br />
事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。<br />
信号量包含的几个操作原语：</p>

<div class="wp_codebox"><table><tr id="p3598"><td class="code" id="p359code8"><pre class="cpp" style="font-family:monospace;">   　　CreateEvent（） 创建一个信号量
   　　OpenEvent（） 打开一个事件
   　　SetEvent（） 回置事件
   　　WaitForSingleObject（） 等待一个事件
   　　WaitForMultipleObjects（）　　　　　　　　 等待多个事件
   　　WaitForMultipleObjects 函数原型：
   　　WaitForMultipleObjects（
   　　        IN DWORD nCount, <span style="color: #666666;">// 等待句柄数</span>
   　　　　　IN CONST HANDLE <span style="color: #000040;">*</span>lpHandles, <span style="color: #666666;">//指向句柄数组</span>
   　　　　　IN BOOL bWaitAll, <span style="color: #666666;">//是否完全等待标志</span>
   　　　　　IN DWORD dwMilliseconds <span style="color: #666666;">//等待时间</span>
   　　　　　）</pre></td></tr></table></div>

<p>参数nCount指定了要等待的内核对象的数目，存放这些内核对象的数组由lpHandles来指向。fWaitAll对指定的这nCount个内核 对象的两种等待方式进行了指定，为TRUE时当所有对象都被通知时函数才会返回，为FALSE则只要其中任何一个得到通知就可以返回。 dwMilliseconds在这里的作用与在WaitForSingleObject（）中的作用是完全一致的。如果等待超时，函数将返回 WAIT_TIMEOUT。</p>
<p><strong>总结：</strong><br />
1． 互斥量与临界区的作用非常相似，但互斥量是可以命名的，也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多，所以如果只为了在进程内部是用的话使 用临界区会带来速度上的优势并能够减少资源占用量。因为互斥量是跨进程的互斥量一旦被创建，就可以通过名字打开它。<br />
2． 互斥量（Mutex），信号灯（Semaphore），事件（Event）都可以被跨越进程使用来进行同步数据操作，而其他的对象与数据同步操作无关，但 对于进程和线程来讲，如果进程和线程在运行状态则为无信号状态，在退出后为有信号状态。所以可以使用WaitForSingleObject来等待进程和 线程退出。<br />
3． 通过互斥量可以指定资源被独占的方式使用，但如果有下面一种情况通过互斥量就无法处理，比如现在一位用户购买了一份三个并发访问许可的数据库系统，可以根 据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作，这时候如果利用互斥量就没有办法完成这个要求，信号灯对象可以说是一种资源计数 器。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/359.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一致性对SEO的重要性</title>
		<link>http://www.cloved.cn/357.html</link>
		<comments>http://www.cloved.cn/357.html#comments</comments>
		<pubDate>Fri, 18 Mar 2011 05:10:10 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[点滴生活]]></category>
		<category><![CDATA[Seo]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/?p=357</guid>
		<description><![CDATA[如果你问什么是让网站获得某个关键字更靠前排名的必需手段，很多人会提到标题、标签的优化、文章的独特性、反向链接等。 这些的确是SEO的重要因素，但如果你不把这些因素与“坚持”结合起来，它们的成效将非常有限。 比如说，你今天建了一个新站，并且为这个新站添加了很多独特的内容和反向链接，但如果你第二天就开始停止添加新内容新链接，网站很难获得任何有竞争力的关键词的排名。 反之， 即使建站初期你几乎没有特别的内容或反向链接，你仍然可以通过后期的逐渐积累来争取关键字排名。 我们可以通过具体的数字来说明。 假设你现在有两个网站——网站A和网站B——在争取同一个关键字。第一天你就通过社交网站的某些虚拟活动为网站A吸引到了500个反向链接，之后就不常管理了。 而对网站B你采取循序渐进的方法，每两天发表一篇文章，每周增加十个反向链接。 可以确定的是，六个月后网站B的排名一定会高于网站A，这就是“一致性”在起作用。 事实上，谷歌也曾表示其算法考虑了网站的更新频率和对新反向链接的获取。 之后你进行SEO优化时，请记住：缓慢而稳定的步伐也可以获得成功。无论在哪里。 道理很简单，甚至会有人嗤之以鼻，但是坚持，从来就不是简单的事。]]></description>
			<content:encoded><![CDATA[<p>如果你问什么是让网站获得某个关键字更靠前排名的必需手段，很多人会提到标题、标签的优化、文章的独特性、反向链接等。</p>
<p>这些的确是SEO的重要因素，但如果你不把这些因素与“坚持”结合起来，它们的成效将非常有限。</p>
<p>比如说，你今天建了一个新站，并且为这个新站添加了很多独特的内容和反向链接，但如果你第二天就开始停止添加新内容新链接，网站很难获得任何有竞争力的关键词的排名。</p>
<p>反之， 即使建站初期你几乎没有特别的内容或反向链接，你仍然可以通过后期的逐渐积累来争取关键字排名。</p>
<p>我们可以通过具体的数字来说明。 假设你现在有两个网站——网站A和网站B——在争取同一个关键字。第一天你就通过社交网站的某些虚拟活动为网站A吸引到了500个反向链接，之后就不常管理了。 而对网站B你采取循序渐进的方法，每两天发表一篇文章，每周增加十个反向链接。 可以确定的是，六个月后网站B的排名一定会高于网站A，这就是“一致性”在起作用。</p>
<p>事实上，谷歌也曾表示其算法考虑了网站的更新频率和对新反向链接的获取。</p>
<p>之后你进行SEO优化时，请记住：缓慢而稳定的步伐也可以获得成功。无论在哪里。</p>
<p>道理很简单，甚至会有人嗤之以鼻，但是坚持，从来就不是简单的事。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/357.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>高效 JavaScript</title>
		<link>http://www.cloved.cn/352.html</link>
		<comments>http://www.cloved.cn/352.html#comments</comments>
		<pubDate>Fri, 18 Mar 2011 04:59:04 +0000</pubDate>
		<dc:creator>许石南</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[appendChild]]></category>
		<category><![CDATA[Display]]></category>
		<category><![CDATA[getElementById]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[opera 9]]></category>
		<category><![CDATA[opera web]]></category>
		<category><![CDATA[reflow]]></category>
		<category><![CDATA[return test]]></category>
		<category><![CDATA[script location]]></category>
		<category><![CDATA[var]]></category>
		<category><![CDATA[web opera]]></category>
		<category><![CDATA[高效]]></category>

		<guid isPermaLink="false">http://www.cloved.cn/?p=352</guid>
		<description><![CDATA[传统上，网页中不会有大量的脚本，至少脚本很少会影响网页的性能。但随着网页越来越像 Web 应用程序，脚本的效率对网页性能影响越来越大。而且使用 Web 技术开发的应用程序现在越来越多，因此提高脚本的性能变得很重要。 对于桌面应用程序，通常使用编译器将源代码转换为二进制程序。编译器可以花费大量时间优化最终二进制程序的效率。Web 应用程序则不同。因为 Web 应用程序需要运行在不同的浏览器、平台和架构中，不可能事先完全编译。浏览器在获得脚本后要执行解释和编译工作。用户要求不仅要求网页能快速的载入，而且要求最终 Web 应用程序执行的效果要和桌面应用程序的一样流畅。Web 应用程序应能运行在多种设备上，从普通的桌面电脑到手机。 浏览器并不很擅长此项工作。虽然 Opera 有着当前最快的脚本引擎，但浏览器有不可避免的局限性，这时就需要 Web 开发者的帮助。Web 开发者提高 Web 应用程序的性能的方法很多而且也很简单，如只需要将一种循环变成另一种、将组合样式分解成三个或者只添加实际需要的脚本。...]]></description>
			<content:encoded><![CDATA[<p>传统上，网页中不会有大量的脚本，至少脚本很少会影响网页的性能。但随着网页越来越像 Web 应用程序，脚本的效率对网页性能影响越来越大。而且使用 Web 技术开发的应用程序现在越来越多，因此提高脚本的性能变得很重要。</p>
<p>对于桌面应用程序，通常使用编译器将源代码转换为二进制程序。编译器可以花费大量时间优化最终二进制程序的效率。Web 应用程序则不同。因为 Web 应用程序需要运行在不同的浏览器、平台和架构中，不可能事先完全编译。浏览器在获得脚本后要执行解释和编译工作。用户要求不仅要求网页能快速的载入，而且要求最终 Web 应用程序执行的效果要和桌面应用程序的一样流畅。Web 应用程序应能运行在多种设备上，从普通的桌面电脑到手机。</p>
<p>浏览器并不很擅长此项工作。虽然 Opera 有着当前最快的脚本引擎，但浏览器有不可避免的局限性，这时就需要 Web 开发者的帮助。Web 开发者提高 Web 应用程序的性能的方法很多而且也很简单，如只需要将一种循环变成另一种、将组合样式分解成三个或者只添加实际需要的脚本。</p>
<p>本文从 ECMAScript/javascript, DOM, 和页面载入方面分别介绍几种简单的能提高 Web 应用程序性能的方法。</p>
<p>原文地址：http://www.woiweb.net/efficient-javascript.html</p>
<p>目录<br />
<strong>ECMAScript</strong><br />
<strong> 避免使用 eval 或 Function 构造函数</strong><br />
<strong> 重写 eval</strong><br />
<strong> 如果你需要函数，那就用函数</strong><br />
<strong> 避免使用 with</strong><br />
<strong> 不要在影响性能的关键函数中使用 try-catch-finally</strong><br />
<strong> 分隔 eval 和 with</strong><br />
<strong> 避免使用全局变量</strong><br />
<strong> 注意隐式对象转换</strong><br />
<strong> 在关键函数中避免 for-in</strong><br />
<strong> 优化 string 合并</strong><br />
<strong> 基本运算符比函数调用更快</strong><br />
<strong> 向 setTimeout() 和 setInterval()传送函数名，而不要传送字符串</strong><br />
<strong> DOM</strong><br />
<strong> 重绘和 reflow</strong><br />
<strong> 减少 reflow 次数</strong><br />
<strong> 最小化 reflow 影响</strong><br />
<strong> 修改 DOM 树</strong><br />
<strong> 修改不可见元素</strong><br />
<strong> 测量大小</strong><br />
<strong> 一次修改多个样式值</strong><br />
<strong> 用流畅性换取速度</strong><br />
<strong> 避免搜索大量节点</strong><br />
<strong> 使用 XPath 提高速度</strong><br />
<strong> 避免在遍历 DOM 时修改 DOM</strong><br />
<strong> 使用变量保存 DOM 值</strong><br />
<strong> 页面载入</strong><br />
<strong> 避免保存来自其他文档的引用</strong><br />
<strong> 快速历史浏览</strong><br />
<strong> 使用 XMLHttpRequest</strong><br />
<strong> 动态创建 SCRIPT 元素</strong><br />
<strong> location.replace() 控制历史项</strong></p>
<p><strong></strong><br />
<span style="color: #ff0000;"><strong>ECMAScript</strong></span><br />
<span style="color: #ff0000;"><strong> 避免使用 eval 或 Function 构造函数</strong></span><br />
每次 eval 或 Function 构造函数作用于字符串表示的源代码时，脚本引擎都需要将源代码转换成可执行代码。这是很消耗资源的操作 —— 通常比简单的函数调用慢100倍以上。</p>
<p>eval 函数效率特别低，由于事先无法知晓传给 eval 的字符串中的内容，eval在其上下文中解释要处理的代码，也就是说编译器无法优化上下文，因此只能有浏览器在运行时解释代码。这对性能影响很大。</p>
<p>Function 构造函数比 eval 略好，因为使用此代码不会影响周围代码；但其速度仍很慢。</p>
<p><strong><span style="color: #ff0000;">重写 eval</span></strong><br />
eval 不仅效率低下，而且绝大部分情况下完全没有使用的必要。很多情况下使用 eval 是因为信息以字符串形式提供，开发者误认为只有 eval 能使用此信息。下例是一个典型的错误：</p>

<div class="wp_codebox"><table><tr id="p35251"><td class="code" id="p352code51"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> getProperty<span style="color: #009900;">&#40;</span>oString<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> oReference<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'oReference = test.prop.'</span><span style="color: #339933;">+</span>oString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> oReference<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>下面的代码执行完全相同的函数，但没有使用 eval：</p>

<div class="wp_codebox"><table><tr id="p35252"><td class="code" id="p352code52"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> getProperty<span style="color: #009900;">&#40;</span>oString<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">return</span> test.<span style="color: #660066;">prop</span><span style="color: #009900;">&#91;</span>oString<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>在 Opera 9, Firefox, 和 Internet Explorer 中后者比前者快95%，在 Safari 中快85%。(注意此比较中不含函数本身调用时间。)</p>
<p><span style="color: #ff0000;"><strong>如果你需要函数，那就用函数</strong></span><br />
下面是常见的 Function 构造函数使用：</p>

<div class="wp_codebox"><table><tr id="p35253"><td class="code" id="p352code53"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> addMethod<span style="color: #009900;">&#40;</span>oObject<span style="color: #339933;">,</span>oProperty<span style="color: #339933;">,</span>oFunctionCode<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
oObject<span style="color: #009900;">&#91;</span>oProperty<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> <span style="color: #003366; font-weight: bold;">Function</span><span style="color: #009900;">&#40;</span>oFunctionCode<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
addMethod<span style="color: #009900;">&#40;</span>myObject<span style="color: #339933;">,</span><span style="color: #3366CC;">'rotateBy90'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'this.angle=(this.angle+90)%360'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
addMethod<span style="color: #009900;">&#40;</span>myObject<span style="color: #339933;">,</span><span style="color: #3366CC;">'rotateBy60'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'this.angle=(this.angle+60)%360'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>下面的代码没有使用 Function 构造函数，但提供了相同的功能：通过创建匿名函数：</p>

<div class="wp_codebox"><table><tr id="p35254"><td class="code" id="p352code54"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> addMethod<span style="color: #009900;">&#40;</span>oObject<span style="color: #339933;">,</span>oProperty<span style="color: #339933;">,</span>oFunction<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
oObject<span style="color: #009900;">&#91;</span>oProperty<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> oFunction<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
addMethod<span style="color: #009900;">&#40;</span>myObject<span style="color: #339933;">,</span><span style="color: #3366CC;">'rotateBy90'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">angle</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">angle</span><span style="color: #339933;">+</span><span style="color: #CC0000;">90</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span>360<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
addMethod<span style="color: #009900;">&#40;</span>myObject<span style="color: #339933;">,</span><span style="color: #3366CC;">'rotateBy60'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">angle</span><span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">angle</span><span style="color: #339933;">+</span><span style="color: #CC0000;">60</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span>360<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>避免使用 with</strong></span><br />
尽管看起来挺方便，但 with 效率很低。with 结构又创建了一个作用域，以便使用变量时脚本引擎搜索。这本身只轻微的影响性能。但严重的是编译时不知道此作用域内容，因此编译器无法像对其他作用域（如函数产生的作用域）那样对之优化。</p>
<p>另一个高效而且也挺方便的方法是使用变量引用对象，然后使用变量访问对象属性。但只有属性不是 literal type 时才适用，如字符串或布尔值。</p>
<p>考虑下面的代码：</p>

<div class="wp_codebox"><table><tr id="p35255"><td class="code" id="p352code55"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">with</span><span style="color: #009900;">&#40;</span> test.<span style="color: #660066;">information</span>.<span style="color: #660066;">settings</span>.<span style="color: #660066;">files</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
primary <span style="color: #339933;">=</span> <span style="color: #3366CC;">'names'</span><span style="color: #339933;">;</span>
secondary <span style="color: #339933;">=</span> <span style="color: #3366CC;">'roles'</span><span style="color: #339933;">;</span>
tertiary <span style="color: #339933;">=</span> <span style="color: #3366CC;">'references'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>下面的代码效率更高：</p>

<div class="wp_codebox"><table><tr id="p35256"><td class="code" id="p352code56"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> testObject <span style="color: #339933;">=</span> test.<span style="color: #660066;">information</span>.<span style="color: #660066;">settings</span>.<span style="color: #660066;">files</span><span style="color: #339933;">;</span>
testObject.<span style="color: #660066;">primary</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'names'</span><span style="color: #339933;">;</span>
testObject.<span style="color: #660066;">secondary</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'roles'</span><span style="color: #339933;">;</span>
testObject.<span style="color: #660066;">tertiary</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'references'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>不要在影响性能的关键函数中使用 try-catch-finally</strong></span><br />
try-catch-finally 结构比较特殊。和其他语法结构不同，它在 runtime 的当前作用域中创建新变量。每当catch 执行时，就会将捕获到的 exception 对象赋给一个变量。这个变量不属于任何脚本。它在 catch 语句开始时被创建，在结束时被销毁。</p>
<p>由于此函数比较特殊，且是在运行时动态创建动态销毁，有些浏览器对其的处理并不高效。把 catch 语句放在关键循环中将极大影响性能。</p>
<p>如果可能，应在脚本中不频繁被调用的地方进行异常处理，或通过检查某种动作是否被支持来避免使用。下面的例子中，如果所需的属性不存在，将在循环语句中抛出许多异常：</p>

<div class="wp_codebox"><table><tr id="p35257"><td class="code" id="p352code57"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oProperties <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'first'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'second'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'third'</span><span style="color: #339933;">,</span>...<span style="color: #339933;">,</span><span style="color: #3366CC;">'nth'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> i<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> oProperties.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
test<span style="color: #009900;">&#91;</span>oProperties<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">someproperty</span> <span style="color: #339933;">=</span> somevalue<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>很多情况下，可把 try-catch-finally 结构移到循环外部。这样做稍微改变了程序语义，因为如果抛出异常，将停止整个循环：</p>

<div class="wp_codebox"><table><tr id="p35258"><td class="code" id="p352code58"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oProperties <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'first'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'second'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'third'</span><span style="color: #339933;">,</span>...<span style="color: #339933;">,</span><span style="color: #3366CC;">'nth'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> i<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> oProperties.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
test<span style="color: #009900;">&#91;</span>oProperties<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">someproperty</span> <span style="color: #339933;">=</span> somevalue<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>有时可用属性检测或其他检测代替 try-catch-finally 结构：</p>

<div class="wp_codebox"><table><tr id="p35259"><td class="code" id="p352code59"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oProperties <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'first'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'second'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'third'</span><span style="color: #339933;">,</span>...<span style="color: #339933;">,</span><span style="color: #3366CC;">'nth'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> i<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> oProperties.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> test<span style="color: #009900;">&#91;</span>oProperties<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
test<span style="color: #009900;">&#91;</span>oProperties<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">someproperty</span> <span style="color: #339933;">=</span> somevalue<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>分隔 eval 和 with</strong></span><br />
因为 eval 和 with 结构严重影响性能，应该尽量避免使用这些结构。但如不得不使用时， 避免在频繁被调用的函数中或循环中使用这些结构。最好将这些结构放在只运行一次，或少量几次的代码中，并不要将其放在对性能要求较高的代码中。</p>
<p>如果可能，尽量将这些结构和其他代码分隔开，这样他们就不会影响脚本性能。如将其放在顶级函数中，或只执行一次然后保存运行结果，避免再次使用。</p>
<p>try-catch-finally 结构在一些浏览器中也会影响性能，包括 Opera ，因此最好也将其分隔。</p>
<p>避免使用全局变量<br />
全局变量使用简单，因此很容易禁不住诱惑在脚本中使用全局变量。但有时全局变量也会影响脚本性能。</p>
<p>首先，如果函数或其他作用域内引用了全局变量，则脚本引擎不得不一级一级查看作用域直到搜索到全局作用域。查询本地作用域变量更快。</p>
<p>其次，全局变量将始终存在在脚本生命周期中。而本地变量在本地作用域结束后就将被销毁，其所使用的内存也会被垃圾收集器回收。</p>
<p>最后，window 对象也共享全局作用域，也就是说本质上是两个作用域而不是一个。使用全局变量不能像使用本地变量那样使用前缀，因此脚本引擎要花更多时间查找全局变量。</p>
<p>也可在全局作用域中创建全局函数。函数中可以调用其他函数，随着函数调用级数增加，脚本引擎需要花更多时间才能找到全局变量以找到全局变量。</p>
<p>考虑下面的简单例子，i 和 s 是全局作用域且函数使用这两个全局变量：</p>

<div class="wp_codebox"><table><tr id="p35260"><td class="code" id="p352code60"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span> s <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> testfunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
s <span style="color: #339933;">+=</span> i<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
testfunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>下面的函数效率更高。在大多数浏览器中，包括 Opera 9、最新版 Internet Explorer, Firefox, Konqueror 和 Safari，后者执行速度比上面代码快30%。</p>

<div class="wp_codebox"><table><tr id="p35261"><td class="code" id="p352code61"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> testfunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">,</span> s <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #CC0000;">20</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
s <span style="color: #339933;">+=</span> i<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
testfunction<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>注意隐式对象转换</strong></span><br />
Literal，如字符串、数字和布尔值在 ECMAScript 中有两种表示方法。 每个类型都可以创建变量值或对象。如var oString = &#8216;some content&#8217;;, 创建了字符串值，而 var oString = new String(&#8216;some content&#8217;);创建了字符串对象。</p>
<p>所有的属性和方法都定义在 string 对象中，而不是 string 值中。每次使用 string 值的方法或属性， ECMAScript 引擎都会隐式的用相同 string 值创建新的 string 对象。此对象只用于此请求，以后每次视图调用 string 值方法是都会重新创建。</p>
<p>下面的代码将要求脚本引擎创建21个新 string 对象，每次使用 length 属性时都会产生一个，每一个 charAt 方法也会产生一个：</p>

<div class="wp_codebox"><table><tr id="p35262"><td class="code" id="p352code62"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> <span style="color: #3366CC;">'0123456789'</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> s.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
s.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>下面的代码和上面相同，但只创建了一个对象，因此其效率更高：</p>

<div class="wp_codebox"><table><tr id="p35263"><td class="code" id="p352code63"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> String<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'0123456789'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> s.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
s.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>如果代码中常调用 literal 值的方法，你应像上面例子那样考虑创建对象。</p>
<p>注意本文中大部分技巧对于所有浏览器都有效，但此技巧特别针对于 Opera。此优化技巧在 Internet Explorer 和 Firefox 中改进效果没有在 Opera 中明显。</p>
<p><span style="color: #ff0000;"><strong>在关键函数中避免 for-in</strong></span><br />
for-in 常被误用，特别是简单的 for 循环更合适时。for-in 循环需要脚本引擎创建所有可枚举的属性列表，然后检查是否存在重复。</p>
<p>有时脚本已知可枚举的属性。这时简单的 for 循环即可遍历所有属性，特别是当使用顺序数字枚举时，如数组中。</p>
<p>下面是不正确的 for-in 循环使用：</p>

<div class="wp_codebox"><table><tr id="p35264"><td class="code" id="p352code64"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oSum <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #000066; font-weight: bold;">in</span> oArray <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
oSum <span style="color: #339933;">+=</span> oArray<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>for 循环无疑会更高效：</p>

<div class="wp_codebox"><table><tr id="p35265"><td class="code" id="p352code65"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> oSum <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oLength <span style="color: #339933;">=</span> oArray.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> oLength<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
oSum <span style="color: #339933;">+=</span> oArray<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong><span style="color: #ff0000;">优化 string 合并</span></strong><br />
字符串合并是比较慢的。+ 运算符并不管是否将结果保存在变量中。它会创建新 string 对象，并将结果赋给此对象；也许新对象会被赋给某个变量。下面是一个常见的字符串合并语句：</p>

<div class="wp_codebox"><table><tr id="p35266"><td class="code" id="p352code66"><pre class="javascript" style="font-family:monospace;">a <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'x'</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'y'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>此代码首先创建临时string对象保存合并后的’xy’值，然后和a变量合并，最后将结果赋给a。下面的代码使用两条分开的命令，但每次都直接赋值给a ，因此不需要创建临时string对象。结果在大部分浏览器中，后者比前者快20%，而且消耗更少的内存：</p>

<div class="wp_codebox"><table><tr id="p35267"><td class="code" id="p352code67"><pre class="javascript" style="font-family:monospace;">a <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'x'</span><span style="color: #339933;">;</span>
a <span style="color: #339933;">+=</span> <span style="color: #3366CC;">'y'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong><span style="color: #ff0000;">基本运算符比函数调用更快</span></strong><br />
尽管单独使用效果不明显，但如果在需要高性能的关键循环和函数中使用基本运算符代替函数调用将可能提高脚本性能。例子包括数组的 push 方法，其效率低于直接在数组末位赋值。另一个例子是 Math 对象方法，大部分情况下，简单的数学运算符效率更高更合适。</p>

<div class="wp_codebox"><table><tr id="p35268"><td class="code" id="p352code68"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> min <span style="color: #339933;">=</span> Math.<span style="color: #660066;">min</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
A.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>下面代码实现相同功能，但效率更高：</p>

<div class="wp_codebox"><table><tr id="p35269"><td class="code" id="p352code69"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> min <span style="color: #339933;">=</span> a <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> b <span style="color: #339933;">?</span> a <span style="color: #339933;">:</span> b<span style="color: #339933;">;</span>
A<span style="color: #009900;">&#91;</span>A.<span style="color: #660066;">length</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> v<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>向 setTimeout() 和 setInterval()传送函数名，而不要传送字符串</strong></span><br />
setTimeout() 和 setInterval() 方法近似于 eval。如果传进参数是字符串，则在一段时间之后，会和eval一样执行字符串值，当然其低效率也和 eval 一样。</p>
<p>但这些方法也可以接受函数作为第一个参数。在一段时间后将调用此函数，但此函数可在编译时被解释和优化，也就是说会有更好的性能。典型的使用 string 作为参数例子如下：</p>

<div class="wp_codebox"><table><tr id="p35270"><td class="code" id="p352code70"><pre class="javascript" style="font-family:monospace;">setInterval<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'updateResults()'</span><span style="color: #339933;">,</span><span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
setTimeout<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'x+=3;prepareResult();if(!hasCancelled){runmore();}'</span><span style="color: #339933;">,</span><span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>第一个语句可以直接传递函数名。第二个语句中，可以使用匿名函数封装代码：</p>

<div class="wp_codebox"><table><tr id="p35271"><td class="code" id="p352code71"><pre class="javascript" style="font-family:monospace;">setInterval<span style="color: #009900;">&#40;</span>updateResults<span style="color: #339933;">,</span><span style="color: #CC0000;">1000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
x <span style="color: #339933;">+=</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">;</span>
prepareResult<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span>hasCancelled <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
runmore<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>需要注意的是 timeout 或时间延迟可能并不准确。通常浏览器会花比要求更多的时间。有些浏览器会稍微提早完成下一个延迟以补偿。有些浏览器每次可能都会等待准确时间。很多因素，如 CPU 速度、线程状态和 javascript 负载都会影响时间延迟的精度。大多数浏览器无法提供1ms以下的延迟，可能会设置最小可能延迟，通常在10 和 100 ms之间。</p>
<p><span style="color: #ff0000;"><strong>DOM</strong></span><br />
通常主要有三种情况引起 DOM 运行速度变慢。第一就是执行大量 DOM 操作的脚本，如从获取的数据中建造新的 DOM 树。第二种情况是脚本引起太多的 reflow 或重绘。第三种情况是使用较慢的 DOM 节点定位方法。</p>
<p>第二种和第三种情况比较常见且对性能影响比较严重，因此先介绍前两种情况。</p>
<p><span style="color: #ff0000;"><strong>重绘(Repaint)和 reflow</strong></span><br />
重绘也被称为重画，每当以前不可见的元素变得可见（或反之）时就需要重绘操作；重绘不会改变页面布局。如给元素添加轮廓、改变背景颜色、改变样式。重绘对性能影响很大，因为需要脚本引擎搜索所有元素以确定哪些是可见的及哪些是应被显示的。</p>
<p>Reflow 是更大规模的变化。当 DOM 数被改变时、影响布局的样式被修改时、当元素的 className 属性被修改时或当浏览器窗口大小变化时都会引起 reflow。脚本引擎必须 reflow 相关元素以确定哪些部分不应被现实。其子节点也会被 reflow 以考虑其父节点的新布局。DOM 中此元素之后出现的元素也被 reflow 以计算新布局，因为它们的位置可能已被移动了。祖先节点也需要 reflow 以适应子节点大小的改变。总之，所有元素都需被重绘。</p>
<p>Reflow 从性能角度来说是非常耗时的操作，是导致 DOM 脚本较慢的主要原因之一，特别在手机等处理能力较弱的设备上。很多情况下，reflow 和重新布局整个网页耗时相近。</p>
<p><strong><span style="color: #ff0000;">减少 reflow 次数</span></strong><br />
很多情况下脚本需要进行会引起 reflow 或重绘的操作，如动画就需要 reflow 操作，因此 reflow 是 Web 开发不可或缺的特性。为了让脚本能快速运行，应在不影响整体视觉效果的情况下尽量减少 reflow 次数。</p>
<p>浏览器可以选择缓存 reflow 操作，如可以等到脚本线程结束后才 reflow 以呈现变化。Opera 可以等待足够数量的改变后才 reflow、或等待足够长时间后才 reflow、或等待脚本线程结束后才 reflow。也就是说如果一个脚本线程中的发生很多间隔很小的改变时，可能只引起一个 reflow 。但开发者不能依赖此特性，特别是考虑到运行 Opera 的不同设备的运算速度有很大差异。</p>
<p>注意不同元素的 reflow 消耗时间不同。Reflow 表格元素消耗的时间最多是 Reflow 块元素时间的3倍。</p>
<p><span style="color: #ff0000;"><strong>最小化 reflow 影响</strong></span><br />
正常的 reflow 可能影响整个页面。reflow 的页面内容越多，则 reflow 操作的时间也越长。Reflow 的页面内容越多，需要的时间也就越长。位置固定的元素不影响页面的布局，因此如果它们 reflow 则只需 reflow 其本身。其背后的网页需要被重绘，但这比 reflow 整个页面要快得多。</p>
<p>所以动画不应该被用于整个页面，最好用于固定位置元素。大部分动画符合此要求。</p>
<p><span style="color: #ff0000;" colla="+"><strong>修改 DOM 树</strong></span><br />
修改 DOM 树会导致 reflow 。向 DOM 中添加新元素、修改 text 节点值或修改属性都可能导致 reflow。顺序执行多个修改会引起超过一个 reflow，因此最好将多个修改放在不可见的 DOM 树 fragment 中。这样就只需要一次 DOM 修改操作：</p>

<div class="wp_codebox"><table><tr id="p35272"><td class="code" id="p352code72"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> docFragm <span style="color: #339933;">=</span> document.<span style="color: #660066;">createDocumentFragment</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> elem<span style="color: #339933;">,</span> contents<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> textlist.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
elem <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
contents <span style="color: #339933;">=</span> document.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span>textlist<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>contents<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
docFragm.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>docFragm<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>也可以在元素的克隆版本中进行多个 DOM 树修改操作，在修改结束后用克隆版本替换原版本即可，这样只需要一个 reflow 操作。注意如果元素中包含表单控件，则不能使用此技巧，因为用户所做修改将无法反映在 DOM 树种。此技巧也不应该用于绑定事件处理器的元素，因为理论上不应该克隆这些元素。</p>

<div class="wp_codebox"><table><tr id="p35273"><td class="code" id="p352code73"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> original <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'container'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> cloned <span style="color: #339933;">=</span> original.<span style="color: #660066;">cloneNode</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
cloned.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'width'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'50%'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> elem<span style="color: #339933;">,</span> contents<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> textlist.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
elem <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
contents <span style="color: #339933;">=</span> document.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span>textlist<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
elem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>contents<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
cloned.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>elem<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
original.<span style="color: #660066;">parentNode</span>.<span style="color: #660066;">replaceChild</span><span style="color: #009900;">&#40;</span>cloned<span style="color: #339933;">,</span>original<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>修改不可见元素</strong></span><br />
如果一个元素的 display 样式被设置为 none，即使其内容变化也不再需要重绘此元素，因为根本就不会显示此元素。可以利用这一点。如果需要对一个元素或其内容做出多个修改，又无法将这些更改放在一个重绘中，则可以先将元素设置为 display:none ，做出修改后，在把元素改回原来状态。</p>
<p>上面方法将导致两个额外的 reflow，一个是隐藏元素时另一个是重新显示此元素时，但此方法的总体效率仍较高。如果隐藏的元素影响滚动条位置，上面的方法也有可能会引起滚动条跳动。但此技术也被用于固定位置元素而不会引起任何不好看的影响。</p>

<div class="wp_codebox"><table><tr id="p35274"><td class="code" id="p352code74"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> posElem <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'animation'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
posElem.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span>
posElem.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>newNodes<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
posElem.<span style="color: #660066;">style</span>.<span style="color: #660066;">width</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'10em'</span><span style="color: #339933;">;</span>
... <span style="color: #660066;">other</span> changes ...
<span style="color: #660066;">posElem</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'block'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>测量大小</strong></span><br />
如上面所述，浏览器可能会缓存多个修改一起执行，并只执行一次 reflow 。但注意为保证结果正确，测量元素大小也会引起 reflow 。尽管这不会造成任何重绘，但仍会在后台进行 reflow 操作。</p>
<p>使用 offsetWidth 这样的属性或 getComputedStyle 这样的方法都会引起 reflow 。即使不使用返回的结果，上述操作也会引起立即 reflow。如果重复需要测量结果，可以考虑只测量一次但用变量保存结果。</p>

<div class="wp_codebox"><table><tr id="p35275"><td class="code" id="p352code75"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> posElem <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'animation'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> calcWidth <span style="color: #339933;">=</span> posElem.<span style="color: #660066;">offsetWidth</span><span style="color: #339933;">;</span>
posElem.<span style="color: #660066;">style</span>.<span style="color: #660066;">fontSize</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> calcWidth <span style="color: #339933;">/</span> <span style="color: #CC0000;">10</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
posElem.<span style="color: #660066;">firstChild</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">marginLeft</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> calcWidth <span style="color: #339933;">/</span> <span style="color: #CC0000;">20</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
posElem.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">*</span> calcWidth <span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #CC0000;">2</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'px'</span><span style="color: #339933;">;</span>
... <span style="color: #660066;">other</span> changes ...</pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>一次修改多个样式值</strong></span><br />
与 DOM 树修改相似，可将多个样式修改一次进行，以尽量减少重绘或 reflow数目。常见设置样式方法是逐个设置：</p>

<div class="wp_codebox"><table><tr id="p35276"><td class="code" id="p352code76"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> toChange <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mainelement'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
toChange.<span style="color: #660066;">style</span>.<span style="color: #660066;">background</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'#333'</span><span style="color: #339933;">;</span>
toChange.<span style="color: #660066;">style</span>.<span style="color: #660066;">color</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'#fff'</span><span style="color: #339933;">;</span>
toChange.<span style="color: #660066;">style</span>.<span style="color: #660066;">border</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'1px solid #00f'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>上面代码可能引起多次 reflow 和重绘。有两种改进方法。如果元素采用了多个样式，而且这些样式值事先知道，可以通过修改元素 class 使用新样式：</p>

<div class="wp_codebox"><table><tr id="p35277"><td class="code" id="p352code77"><pre class="javascript" style="font-family:monospace;">div <span style="color: #009900;">&#123;</span>
background<span style="color: #339933;">:</span> #ddd<span style="color: #339933;">;</span>
color<span style="color: #339933;">:</span> #000<span style="color: #339933;">;</span>
border<span style="color: #339933;">:</span> 1px solid #000<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
div.<span style="color: #660066;">highlight</span> <span style="color: #009900;">&#123;</span>
background<span style="color: #339933;">:</span> #<span style="color: #CC0000;">333</span><span style="color: #339933;">;</span>
color<span style="color: #339933;">:</span> #fff<span style="color: #339933;">;</span>
border<span style="color: #339933;">:</span> 1px solid #00f<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
...
<span style="color: #660066;">document</span>.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'mainelement'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">className</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'highlight'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>第二种方法是为元素定义新样式，而不是一个个赋值。这主要用于动态修改，如在动画中，无法事前知道新样式值。通过使用 style 对象的 cssText 属性，或者通过 setAttribute. 可以实现此技巧。Internet Explorer 不允许第二种形式，支持第一种形式。有些较老的浏览器，包括 Opera 8 需要使用第二种形式，不支持第一种形式。最简单的方式是测试看是否支持第一种形式，如果支持就使用，如果不支持则使用第二种形式。</p>

<div class="wp_codebox"><table><tr id="p35278"><td class="code" id="p352code78"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> posElem <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'animation'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> newStyle <span style="color: #339933;">=</span> <span style="color: #3366CC;">'background: '</span> <span style="color: #339933;">+</span> newBack <span style="color: #339933;">+</span> <span style="color: #3366CC;">';'</span> <span style="color: #339933;">+</span>
<span style="color: #3366CC;">'color: '</span> <span style="color: #339933;">+</span> newColor <span style="color: #339933;">+</span> <span style="color: #3366CC;">';'</span> <span style="color: #339933;">+</span>
<span style="color: #3366CC;">'border: '</span> <span style="color: #339933;">+</span> newBorder <span style="color: #339933;">+</span> <span style="color: #3366CC;">';'</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span> posElem.<span style="color: #660066;">style</span>.<span style="color: #660066;">cssText</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
posElem.<span style="color: #660066;">style</span>.<span style="color: #660066;">cssText</span> <span style="color: #339933;">=</span> newStyle<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
posElem.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'style'</span><span style="color: #339933;">,</span>newStyle<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>用流畅性换取速度</strong></span><br />
作为开发者，当然想要动画运行的越流畅越好，通常使用较小的时间间隔或较小的变化。如每10ms更新一次动画，或者每次移动1个像素。此动画可能在桌面电脑上或某些浏览器中可以完美运行。但10ms时间间隔可能是浏览器使用100%CPU才能达到的最小值。有些浏览器甚至不能完成——要求每秒100个 reflow 对大部分浏览器来说都不容易。低性能的电脑或者其他设备可能无法达到此种速度，在这些设备上动画可能非常慢甚至失去响应。</p>
<p>因此最好暂时把开发者的骄傲放在一边，牺牲流畅性而换取速度。把时间间隔改为50ms或把动画步长设为5个像素，会消耗更少的计算资源，在低性能设备上也能正常运行。</p>
<p>避免搜索大量节点<br />
当需要查找节点时，尽量使用 DOM 内置方法和集合缩小搜索范围。如你想要定位某个包含某种属性的元素，可使用下面代码：</p>

<div class="wp_codebox"><table><tr id="p35279"><td class="code" id="p352code79"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> allElements <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> allElements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> allElements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">hasAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'someattr'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>即使没听说过 XPath 这样的高级技巧，也可以看出上面的代码有两个问题导致速度变慢。首先它搜索每一个元素，而不是尝试缩小搜索范围。其次即使已经找到所需元素上卖弄代码还继续搜索。如果已知要找的元素在 id 为inhere的 div 中，最好使用下面的代码：</p>

<div class="wp_codebox"><table><tr id="p35280"><td class="code" id="p352code80"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> allElements <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'inhere'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> allElements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> allElements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">hasAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'someattr'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>如果已知要找元素是 div 的直接子节点，则下面的代码速度更快：</p>

<div class="wp_codebox"><table><tr id="p35281"><td class="code" id="p352code81"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> allChildren <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'inhere'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">childNodes</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> allChildren.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> allChildren<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">nodeType</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> allChildren<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">hasAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'someattr'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>基本的思想就是尽量避免逐个查看 DOM 节点。DOM 有很多更好更快的方法，如 DOM 2 Traversal TreeWalker，效率要高于递归查找 childNodes 集合。</p>
<p><span style="color: #ff0000;"><strong>使用 XPath 提高速度</strong></span><br />
假如需要基于 H2-H4 元素在 html 网页中创建目录。在 html 中标题元素可以出现在很多地方，因此无法使用递归函数获取这些元素。传统 DOM 可能使用如下方法：</p>

<div class="wp_codebox"><table><tr id="p35282"><td class="code" id="p352code82"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> allElements <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> allElements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> allElements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">tagName</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^h[2-4]$/i</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>若网页有超过2000个元素，此方法速度会很慢。如果支持 XPath，则可以使用一个快得多的方法，因为 XPath 查询引擎可比需被解释的 JavaScript 更好的被优化。在有些情况下，XPath 速度可能会快2个数量级以上。下面代码和上面完成一样的功能，但使用 XPath 因此速度要更快：</p>

<div class="wp_codebox"><table><tr id="p35283"><td class="code" id="p352code83"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> headings <span style="color: #339933;">=</span> document.<span style="color: #660066;">evaluate</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">'//h2|//h3|//h4'</span><span style="color: #339933;">,</span> document<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> XPathResult.<span style="color: #660066;">ORDERED_NODE_ITERATOR_TYPE</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oneheading<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span> oneheading <span style="color: #339933;">=</span> headings.<span style="color: #660066;">iterateNext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>下面版本代码融合上述两种方法；在支持 XPath 的地方使用快速方法，在不支持时使用传统 DOM 方法：</p>

<div class="wp_codebox"><table><tr id="p35284"><td class="code" id="p352code84"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> document.<span style="color: #660066;">evaluate</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> headings <span style="color: #339933;">=</span> document.<span style="color: #660066;">evaluate</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">'//h2|//h3|//h4'</span><span style="color: #339933;">,</span> document<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> XPathResult.<span style="color: #660066;">ORDERED_NODE_ITERATOR_TYPE</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> oneheading<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span> oneheading <span style="color: #339933;">=</span> headings.<span style="color: #660066;">iterateNext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
<span style="color: #003366; font-weight: bold;">var</span> allElements <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> allElements.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> allElements<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">tagName</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^h[2-4]$/i</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
...
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>避免在遍历 DOM 时修改 DOM</strong></span><br />
有些 DOM 集合是实时的，如果在你的脚本遍历列表时相关元素产生变化，则此集合会立刻变化而不需要等待脚本遍历结束。childNodes 集合和 getElementsByTagName 返回的节点列表都是这样的实时集合。</p>
<p>如果在遍历这样的集合的同时向其中添加元素，则可能会遇到无限循环，因为你不停的向列表中添加元素，永远也不会碰到列表结束。这不是唯一的问题。为提高性能，可能会对这些集合做出优化，如记住其长度、记住脚本中上一个访问元素序号，这样在你访问下一个元素时可快速定位。</p>
<p>如果你此时修改 DOM 树，即使修改的元素不在此集合中，集合还是会重新搜索以查看是否有新元素。这样就无法记住上一个访问元素序号或记住集合长度，因为集合本身可能已经变了，这样就无法使用优化：</p>

<div class="wp_codebox"><table><tr id="p35285"><td class="code" id="p352code85"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> allPara <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> allPara.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
allPara<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>下面的代码在 Opera 和 Internet Explorer 等主流浏览器中比上面代码快10倍以上。先创建一个要修改元素的静态列表，然后遍历静态列表并作出相应修改，而不是遍历 getElementsByTagName 返回的节点列表：</p>

<div class="wp_codebox"><table><tr id="p35286"><td class="code" id="p352code86"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> allPara <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> collectTemp <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> allPara.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
collectTemp<span style="color: #009900;">&#91;</span>collectTemp.<span style="color: #660066;">length</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> allPara<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> collectTemp.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
collectTemp<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
collectTemp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>使用变量保存 DOM 值</strong></span><br />
有些 DOM 返回值无法缓存，每次调用时都会重新调用函数。如 getElementById 方法。下面是一个低效率代码的例子：</p>

<div class="wp_codebox"><table><tr id="p35287"><td class="code" id="p352code87"><pre class="javascript" style="font-family:monospace;">document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'test'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">property1</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value1'</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'test'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">property2</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value2'</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'test'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">property3</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value3'</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'test'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">property4</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value4'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>此代码为定位同一个对象调用了四次 getElementById 方法。下面的代码只调用了一次并将结果保存在变量中，单看这一个操作可能比上面单个操作要略慢，因为需要执行赋值语句。但后面不再需要调用 getElementById 方法！下面的代码比上面的代码要快5-10倍：</p>

<div class="wp_codebox"><table><tr id="p35288"><td class="code" id="p352code88"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> sample <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'test'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sample.<span style="color: #660066;">property1</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value1'</span><span style="color: #339933;">;</span>
sample.<span style="color: #660066;">property2</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value2'</span><span style="color: #339933;">;</span>
sample.<span style="color: #660066;">property3</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value3'</span><span style="color: #339933;">;</span>
sample.<span style="color: #660066;">property4</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'value4'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>页面载入</strong></span><br />
<span style="color: #ff0000;"><strong> 避免保存来自其他文档的引用</strong></span><br />
如果文档访问过其他文档中的节点或对象，在脚本结束后避免保留这些引用。如果在全局变量或对象属性中保存过这些引用，通过设置为 null 清除之或者直接删除之。</p>
<p>原因是另一个文档被销毁后，如弹出窗口被关闭，尽管那个文档已经不再了，所有对那个文档中对象的引用都会在内存中保存整个 DOM 树和脚本环境。这也适用那些包含在frame，内联 frame，或 OBJECT 元素中的网页。.</p>

<div class="wp_codebox"><table><tr id="p35289"><td class="code" id="p352code89"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> remoteDoc <span style="color: #339933;">=</span> parent.<span style="color: #660066;">frames</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'sideframe'</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">document</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> remoteContainer <span style="color: #339933;">=</span> remoteDoc.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'content'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> newPara <span style="color: #339933;">=</span> remoteDoc.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
newPara.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>remoteDoc.<span style="color: #660066;">createTextNode</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'new content'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
remoteContainer.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>newPara<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">//remove references</span>
remoteDoc <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
remoteContainer <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
newPara <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>快速历史浏览（history navigation）</strong></span><br />
Opera (和许多其他浏览器) 默认使用快速历史浏览。当用户点击后退或前进时，将记录当前页面的状态及页面中的脚本。当用户回到刚才的页面时，将立即显示刚才的页面，如同从没有离开此页一样。不需要重新载入页面也不需要重新初始化。脚本继续运行，DOM 也和离开此页前完全相同。对用户来说这样反应很快，载入较慢的网页应用程序会有更好的性能。</p>
<p>尽管 Opera 提供开发者控制此行为的方式，最好还是尽量保持快速历史浏览功能。也就是说最好避免会影响此功能的动作，包括提交表单时禁用表单控件或让页面内容透明或不可见的渐出特效。</p>
<p>简单的解决方法是使用 onunload 监听器 reset 渐出效果或重新 enable 表单控件。注意对有些浏览器来说，如 Firefox 和 Safari，为 unload 事件添加监听器会禁用历史浏览。而在 Opera 中禁用提交按钮会导致禁用历史浏览。</p>

<div class="wp_codebox"><table><tr id="p35290"><td class="code" id="p352code90"><pre class="javascript" style="font-family:monospace;">window.<span style="color: #000066;">onunload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
document.<span style="color: #660066;">body</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">opacity</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'1'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>使用 XMLHttpRequest</strong></span><br />
此技巧不一定适用于每一个项目，但它能显著降低从服务器下载数据量，也能避免重载页面时销毁及创建脚本环境的开销。开始时正常载入页面，然后使用 XMLHttpRequest 下载最少量的新内容。这样 JavaScript 环境会一直存在。</p>
<p>注意此方法也可能会导致问题。首先此方法完全破坏历史浏览。尽管可通过内联frame储存信息来解决此问题，但这显然不符合使用 XMLHttpRequest 的初衷。因此尽量少用，只在不需要回退到先前内容时使用。此方法还会影响辅助器具的使用（ assistive device），因为将无法察觉 DOM 已被更改，因此最好在不会引起问题的地方使用XMLHttpRequest。</p>
<p>若 JavaScript 不可用或不支持 XMLHttpRequest 则此技巧也会失效。最简单避免此问题的方法是使用正常链接指向新页面。增加一个检测链接是否被激活的事件处理器。处理器可以探测是否支持 XMLHttpRequest ，如果支持则载入新数据并阻止链接默认动作。载入新数据后，用其取代页面的部分内容，然后 request 对象就可以被销毁并允许垃圾收集器回收内存资源。</p>

<div class="wp_codebox"><table><tr id="p35291"><td class="code" id="p352code91"><pre class="javascript" style="font-family:monospace;">document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'nextlink'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">onclick</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span>window.<span style="color: #660066;">XMLHttpRequest</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> request <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
request.<span style="color: #660066;">onreadystatechange</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> request.<span style="color: #660066;">readyState</span> <span style="color: #339933;">!=</span> <span style="color: #CC0000;">4</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> useResponse <span style="color: #339933;">=</span> request.<span style="color: #660066;">responseText</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">/^</span><span style="color: #009900;">&#91;</span>\w\W<span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>
<span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;container&quot;</span><span style="color: #339933;">&gt;|&amp;</span>lt<span style="color: #339933;">;</span>\<span style="color: #339933;">/</span>div<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span>\s<span style="color: #339933;">*&amp;</span>lt<span style="color: #339933;">;</span>\<span style="color: #339933;">/</span>body<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span><span style="color: #009900;">&#91;</span>\w\W<span style="color: #009900;">&#93;</span><span style="color: #339933;">*</span>$<span style="color: #339933;">/</span>g <span style="color: #339933;">,</span> <span style="color: #3366CC;">''</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'container'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> useResponse<span style="color: #339933;">;</span>
request.<span style="color: #660066;">onreadystatechange</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
request <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
request.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">'GET'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">href</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
request.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p><span style="color: #ff0000;"><strong>动态创建 SCRIPT 元素</strong></span><br />
加载和处理脚本需要时间，但有些脚本在载入后却从来未被使用。载入这样的脚本浪费时间和资源，并影响当前的脚本执行，因此最好不要引用这种不用的脚本。可以通过简单的加载脚本判断需要哪些脚本，并只为后面需要的脚本创建 script 元素。</p>
<p>理论上，这个加载脚本可在页面载入结束后通过创建 SCRIPT 元素加入 DOM。这在所有主流浏览器中都可以正常工作，但这可能对浏览器的提出更多的要求，甚至大于要载入的脚本本身。而且在页面载入之前可能就需要脚本，因此最好在页面加载过程中，通过 document.write 创建 script 标签。记住一定要转义‘/’字符防止终止当前脚本运行：</p>

<div class="wp_codebox"><table><tr id="p35292"><td class="code" id="p352code92"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> document.<span style="color: #660066;">createElement</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> document.<span style="color: #660066;">childNodes</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;script src=&quot;dom.js&quot; type=&quot;text<span style="color: #000099; font-weight: bold;">\/</span>javascript&quot;&gt;&lt;!--mce:0--&gt;&lt;/script&gt;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.cloved.cn/352.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

