<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[Yaohaixiao's Blog]]></title>
  <subtitle type="html"><![CDATA[We design with web standards.]]></subtitle>
  <id>http://www.yaohaixiao.com/</id>
  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/" /> 
  <link rel="self" type="application/atom+xml" href="http://www.yaohaixiao.com/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.8">PJBlog3</generator> 
  <updated>2008-11-16T09:39:52+08:00</updated>

  <entry>
	  <title type="html"><![CDATA[SEO教程--浅谈网站转化率优化 让你的站更实用]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:39:52+08:00</updated>
	  <published>2008-11-16T09:39:52+08:00</published>
		  <summary type="html"><![CDATA[作者：侯庆龙<br/>原文：<a href="http://chinaz.com/Webbiz/Exp/1104431232008.html" target="_blank" rel="external">http://chinaz.com/Webbiz/Exp/1104431232008.html</a><br/><br/><br/><br/>核心提示：初步的效果只能访客引进来，暂时性的提高网站流量，而网站要做强做大，不但要把访客引进入，还要把访客留下来，这就要考虑如何提高网站转化率，认这也是网站发展的关键策略之一。<br/><br/>什么是网站转化率，含义就是当访客访问网站的时候，把访客转化成网站常驻用户，也可以理解为访客到用户的转换，不管是网站<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>优化，还是做竞价广告推广，初步的效果只能访客引进来，暂时性的提高网站流量，而网站要做强做大，不但要把访客引进入，还要把访客留下来，这就要考虑如何提高网站转化率，认这也是网站发展的关键策略之一。<br/><br/>下面侯庆龙将以访客的身份对网站的用户体验进行分析：<br/><br/><strong>第一关，网站速度</strong><br/><br/>首先，当访客进入网站时，首先第一感觉就是网站的打开响应速度，如果首页文件太大，或者网站服务器偏慢，打开速度超过8秒，你就可能永远失去这个访问用户，在此要注意选择高速稳定的服务器与网站代码的精简设计，网站可以采用Div+Css的构造，提升网站打开速度。<br/><br/><strong>第二关，网站形象</strong><br/><br/>网站形象表现主要体现在在网站整体是否符合用户体验，网站要不做到小而精，要不做到大而全，网站内容是关键，扩充完备的网站内容，打造漂亮简洁的网站界面，网站界面清晰，内容明确，让网站的美化度、专业度、信息度都做到最好，提高网站整体形象。<br/><br/><strong>第三关，网站实用</strong><br/><br/>网站实用主要体现在以下几点：<br/><br/>1、尽量符合用户习惯的设计，网站功能是适用;<br/><br/>2、网站层次合理，该突出时就突出，建立清楚的导航层次<br/><br/>3、网站设有客服联系方式，当访客有所需，又不知怎么办时，可以随时客服咨询服务;<br/><br/>4、网站互动能力加强，开设用户反馈，网站论坛，网站博客，等互动性栏目，把访客互动起来。<br/><br/>网络营销只能拉来流量，但最重要的是怎样提高转化率，这样网站的用户慢慢堆积，打造具有市场竞争力的网站。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=316" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=316</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[SEO教程--分析网站营销基本步骤]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:36:42+08:00</updated>
	  <published>2008-11-16T09:36:42+08:00</published>
		  <summary type="html"><![CDATA[作者：侯庆龙 <br/>原载：<a href="http://sem.noseo.org.cn/sem-celu.html" target="_blank" rel="external">http://sem.noseo.org.cn/sem-celu.html</a><br/><br/><br/>网站营销是提高网站流量，坚立网站形象的方法，今天Seoer惜缘谈谈网站营销的基本步骤：<br/><br/><strong>一：定位分析</strong><br/><br/>网站剖析：对网站的自身行业进行分析;<br/><br/>电子商务定位：对网站进行行业定位，明确网站的基本;<br/><br/>模式分析：分析网站的同行商业模式，研究与网站相匹配的电子商务模式;<br/><br/>行业竞争分析：分析行业竞争，总结综合分析;<br/><br/>网站发展分析：网站短期规划与长期发展战略基本方针等。<br/><br/><strong>二：网站建设分析</strong><br/><br/>1：网站诊断<br/><br/>网站结构诊断：网站的结构是否合理，是否高效，是否方便，是否符合用户访问的习惯;<br/><br/>网站页面诊断：页面代码是否精简，页面是否清晰，页面容量是否合适，页面色彩是否恰当;<br/><br/>文件与文件名诊断：文件格式，文件名等;<br/><br/>访问系统分析：统计系统安装，来路分析，地区分析，访问者分析、关键词分析等;<br/><br/>对网站进行分析。从分析中，总结网站要推广优化一些关键字，使之突出行业搜索竞争力。让用户通过一些行业关键词能找到网站。<br/><br/><strong>三：网站进行优化</strong><br/><br/>网站的架构优化：结构优化，框架优化等;<br/><br/>网站页面优化：页面布局，页面设计优化，图片优化等;<br/><br/>导航设计：导航的方便性，导航的文字优化等;<br/><br/>链接整理：对网站的内外链接进行合理构建;<br/><br/>标签优化设计：对相关页面标签进行关键词优化设计。<br/><br/><strong>四、整合推广</strong><br/><br/>网站流量推广策略：关键还是流量问题，这个过程中会用到许多网络营销方法;<br/><br/>外部链接推广：友情链接策略的使用;<br/><br/>信息群发推广策略：通过对行业内网站进行分析，SEM推广发布产品信息。<br/><br/>其它推广：关注网络变化，开发新的推广手段。<br/><br/><strong>五、网站运作</strong><br/><br/>网站设有在线客服,如QQ、UC、阿里旺旺等.<br/><br/>随时根据产品的特点与更新及时添加相应叙述。<br/><br/>根据行情,调整网络结构，加大推广力度.]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=315" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=315</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[SEO教程--SEO个性化网页权重研究]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:32:03+08:00</updated>
	  <published>2008-11-16T09:32:03+08:00</published>
		  <summary type="html"><![CDATA[来源：<a target="_blank" href="http://www.seo.com.cn" rel="external">思亿欧网络科技</a><br/><br/><br/>目前关于个性化PageRank，其他的常见方法还有模型化PageRank(modular PageRank)和BlockRank等。这些方法在具体的计算方法上，主要的特点体现在从效率的角度上对算法进行了必要的优化。<br/><br/>关于加速PageRank算法的先前研究内容主要使用稀疏性图结构技术，比如Arasu等提出的观点，他们不仅仅单纯使用上次迭代循环产生值来计算本轮循环值，也使用本轮循环已经产生的值来加速本轮循环的计算。甚至提出了Web网络的蝴蝶结结构，并将其用于PageRank值的有效计算中。然而这些方法并不具有很大的实用性，主要原因在于算法要求对Web网络矩阵进行排序，这个操作需要按照深度搜索优先的原则进行网络遍历，这显然是一种代价极大的运算。最近Kamvar等也提出一些算法，使用连续中间循环来推断真实PageRank更好的估计值，但是仍然存在受PageRank算法初始参数影响的不足之处。<br/><br/>目前对于Web网络图结构的分析主要关注于研究图的属性，如节点的分布、网页链接的情况和Web网页图结构的建模等。然而，对于这些研究并没有强调如何有效利用这些属性来加快超链分析。<br/><br/>不少学者提出了一些改进做法，如Raghavan和Garcia-Molina等利用主机名称或者URL隐含的Web结构来代表Web图更为成功的做法也有很多，如Jeh和Widom通过有限修改网页的权值来表达的个性化网页权重，这个重要性权值可以反映用户指定的初始兴趣网页。由于对个性化视图的计算需要反复遍历整个Web图结构中的网页，这只有在运行期间才能实现，所以事先计算和存储所有的个性化视图并不现实。他们利用新的图论结果和技术构建出表达个性化视图的“偏好向量”(partial vector)，它可以在不同用户的个性化视图中共享，同时关于它的计算和存储花费与视图数量的多少呈现出合理的比例。在计算中，还可以采用递增式计算，这就使得在查询期间利用偏好向量去构建个性化视图是可行的。这个偏好向量即为个性化PageRank向量(personalized PageRank vector，PPV)，通俗地说，PPV是种Web网页的个性化视图。按照这个PPV来对网页结果进行排序可以有效地表达用户的偏好。<br/><br/>简单地看，每个PPV的长度都为咒，即Web的网页数量。但是由于从一个固定的角度循环计算PPV需要多次遍历Web网页图，这显然是不可能作为一种在线响应用户查询的方式。从另一个角度来看，所有PPV向量的总数量会达到2n(n为网页总数)，这显然又过于巨大而无法实现离线存储。所以，必须将p 集合中出现的网页限制为hub网页集合H的子集。H集合通常包含一些用户最为感兴趣的网页。在实践中，H集合可以是具有较高PageRank值的网页集合 (重要网页)、在人工分类目录中的网页(如Yahoo和Open Directory)、特定企业或程序的重要网页等。H集合可以看成是计算个性化的基础。这种基于PPV的计算方式，不像传统的方式，能够和H集合大小成良好的比例缩放关系，并且这种技术也可以在更大的PPV集合上取得近似的效果，满足一些对于任意偏好网页集合的个性化计算要求。<br/><br/>除此以外，还有一些在计算效果上进行改进的算法。<br/><br/>如一种较为成功的做法是BlockRank方法，它主要是充分利用Web网页间链接结构呈现一种块状结构的特征来改进算法效率。关于Web网络块状结构的特征，已有很多学者进行了论证。例如，据Bharat等的分析，通过对比分析Web网络的链接结构，可以发现近80%左右的网页超链都是同一站点主机内部不同网页间形成的，而不同主机站点间网页的超链比重仅为20%左右。如果去除无用的死链接，这一比重表现得更加不平衡，近似于9：l。进一步将考察范围限定在域名级别后，上述的两个比重都有明显的增加，一为84：16，二为95：5，不平衡性明显加剧。一般在一个主机站点内，大部分的超链由于导航和站点安排，往往会在几个关键的网页上具有较多的内部链接。例如，高校站点内一般会对诸如图书馆、教务处和学生处等网页产生很高的链接比重。其实这种内部链接较高、外部链接较低的情况在不同级别的Web网页图结构中广泛存在，产生了明显的块化现象，而且大部分的块结构都远远小于整个Web的图结构。<br/><br/>这种Web网络所具有的块化结构有助于快速计算PageRank，同时为表达个性化PageRank提供了良好的基础。这个算法的思路大体描述如下：先对每个主机的网页计算本地化的PageRank值，得到在主机内部的相对重要权值。这些本地化的PageRank向量可以进一步按照不同Web网页块的相对重要程度加权形成全局PageRank值的近似值，然后将此PageRank向量作为标准PageRank算法的起始向量。不可否认，个性化 PageRank虽然是个非常吸引人的主意，但是它需要对大规模的PageRank向量进行有效的迭代计算，而使用BlockRank算法和对冲浪者的随机冲浪行为做简单的限制就可以有效地减少个性化PageRank值的计算复杂度。这个限制就是当他厌倦时，他并不是从诸多网页中选择，而是从主机站点中进行选择。也就是说，此时无需考察冲浪者跳转的网页，而只考虑跳转的站点。这时构造的个性化向量具有的维度就是Web网络中主机的个数K，并且向量的元素值也反映冲浪者对不同主机的偏好程度。有了这个限制，本地化PageRank向量就无需针对不同的个性化用户而改变。事实上，本地化的PageRank向量也不会因为矩阵B结构的改变而改变，只有BlockRank向量6才会因为不同的个性化特征而改变，因此只需对每个基于块结构的个性化PageRank向量进行重新计算。<br/><br/>应该说，不论从理论上看，还是从实践上看，利用个性化PageRank来实现搜索引擎的个性化服务是个非常可行的选择，适应Web网络资源对信息检索提出的特点要求。它不仅在推荐结果内容上综合考虑网页客观性权重这个重要指标，而且该方法性能较高，主要计算工作都在离线阶段完成。然而，这些现有的个性化PageRank技术都需要用户登录并主动提交个性化信息，却忽略了用户对Web网页的理解，没有挖掘用户使用行为，收集用户个性化信息的方式不自然，这显然加重了用户的使用负担。所以，虽然说节省了用户挑选相关网页的时间，但是用户却需要花更多的时间去实现搜索个性化。由此可以看出，探讨获取用户个性化信息的其他有效形式将是提高此方法效果的关键所在，本书也主要对此进行研究，探寻更好的个性化信息收集和表达方法以适用于个性化PageRank算法中，该方法较为客观和全面。<br/><br/>个性化网页权重的常见形式就是个性化PageRank。现代搜索引擎对自然搜索引擎排名的排序依据除了使用传统的文本匹配技术以外，也广泛地使用网页权重值来进行。最为有名的例子就是Google的PageRank技术。<br/><br/>利用web结构的链接关系，PageRank可以计算每个网页的权重值，并据此对结果网页进行排序。因此，如果利用用户的偏好信息来修改 PageRank权重值的计算，据此就产生表达特定用户个性化信息需求的搜索引擎排序结果。从效果上看，这种方法较PageRank更为实用，因为毕竟用户是不可能全部遍历获取的查询网页结果集合，所以把和用户需求联系最为密切的网页放于搜索结果前面，必然更易于用户访问。其实，Page等早已提出个性化 PageRank的设想，只是他们并没有在此项研究上深人地开展下去基于个性化网页权重的个性化搜索引擎模型。<br/><br/>现在，人们提出的个性化PageRank方法有很多，主要分为两大类：一类是直接修改基于超链关系得到的网页权重值;另一类是在传统PageRank公式上添加修正参数来反映用户的个性化要求。<br/><br/>在原先的PageRank计算公式中，模型对每个网页的链接分配了相同的概率值，所以这种方法给不同链接和网页分配的权重是一样的，当前网页的权重值也会平均地影响链出网页，同时它还假设用户随机跳转到其他任何网页的概率都是一样的。所以，这种计算方法主要是依赖于网页结构图中的链接来进行分析。但是，这些链接却是由网站的网页设计者生成的，因此它只能反映设计者对Web中其他网页的理解。<br/><br/>另外，这种方法忽略了另外一个重要方面，那就是Web用户对Web网页的理解。也就是说，单纯使用网页之间的超链结构来表达网页权重值是不充分的。比较简单易行的修改网页权重做法就是利用Web日志挖掘信息来获取用户对Web网页的理解程度，以完善传统的PageRank计算方式。事实上，凭直觉可以判断出来，那些访问频率较高的超链应该比那些访问频率较低的超链更为重要，然而大部分的传统超链分析技术对这两者并不加以区分。<br/><br/>对于结合使用信息的超链分析技术最初是由Zhu等提出的，他们把相关公式称为PageRate，虽然他们也宣称自己的算法是PageRank的扩展，但是其实这种算法不具有任何PageRank的性质。这种算法对所有的链入不加区分，并不考虑高频访问和低频访问的区别。同时，他们也没有给出实验结论，对可能存在的问题也没有探讨，设计的公式还存在问题。<br/><br/>有些其他方面的研究也涉及使用信息分析。例如，使用一种增强学习方法来对搜索结果进行重排序和过滤，对于每个查询结果中的URL，系统都会记录不同用户的点击情况。在随后的查询中，上述信息就可以有效地提升高频访问的URL权值，而降低低频访问的URL权值这样的类似方法还应用于一些商业搜索引擎中，如有的学者就在多元搜索引擎中利用上述方法实现一种隐式的相关度反馈机制，它将用户点击产生的使用情况主要用于结果网页合并和网页重排序等操作中旧。用户使用信息还应用于基于模式的应用程序中，主要功能是及时学习用户的兴趣，并对搜索结果重排序以反映这种用户兴趣，如按照用户模式的特征改变不同主题词的相对重要程度。<br/><br/>比较好的方法是利用挖掘Web日志中的信息结合传统PageRank公式得出一种新的网页权重计算公式，即结合使用挖掘的PageRank，如特征敏感的PageRank(usage aware PageRank，UPR)。它结合了静态链接结构分析和用户使用分析两项技术：一方面仍然强调传统网页间的超链关系;另一方面，它通过分析日志，判断这些实际存在的网页超链中究竟哪些是经常被用户访问的，哪些不是经常被用户访问的，并以此来改进传统方法中由超链关系产生的网页权重值。<br/><br/>在UPR方法中，甚至还可以通过调整参数设置来控制静态链接结构分析技术和Web使用挖掘技术的作用力度，如果参数设置为O，公式就等价于传统的 PageRank公式，如果参数设置为1，则重点就转移到使用挖掘分析算法上，介于两者之间则会兼顾，因此这种方式较传统方式更为概括。从效率上看，这种算法也有优势，只需通过一次额外的预处理步骤，其他的迭代处理和传统方式没有区别。<br/><br/>然而这种新的方法也存在不足之处。即使网站管理员可以得到自己站点用户的访问信息，并将其应用于UPR分析，但是这些信息显然没有包含全部的必要信息，如管理员不可能获得不属于自己站点访问内的链出网页使用情况。虽然可以通过爬虫程序遍历那些网页的超链结构，但是除了可以获得用户通过哪些网页的链出网页访问本地网页的使用信息，并不可能获得其他更为重要的使用信息。也就是说，从站点层次上看，全部的结构信息和使用信息是可以全部获取的，然而从整个 Web网络层次上看，却是不完整的。<br/><br/>同时，对单一的应用技术而言，整个Web网络上的用户使用信息也是无法完整获取的。诸如Google搜索工具栏等客户端应用程序，虽然它们可以收集用户的使用信息，而且这些信息也确实是基于整个web范围而言的，然而这里所涉及的用户范围是相当小的，他们首先必须安装客户端应用程序，而且必须进行相关设置以同意公开这些属于个人隐私的Web访问信息。需要说明的是，诸如Google搜索工具栏之类的软件在默认情况下是尊重用户的个人隐私权的，除非用户自己允许，它并不主动收集任何用户访问的信息，当然也有其他一些客户端应用程序似乎并不遵守上述原则。<br/><br/>因此，这种结合使用挖掘的PageRank最适用于网站内部的网页搜索，搜索引擎工作的原理先获取该网站的结构信息，结合用户使用信息，可以得到传统PageRank方法的扩展模型。实验结果也能证明这种算法更能有效地提升高访问频率的网页权重值，相应地降低那些低访问频率的网页权重值。<br/><br/>随着搜索引擎技术慢慢走向成熟，越来越多的搜索引擎优化工作者以及很难从搜索引擎的表象去研究<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>。近一年时间以来，Google、百度等搜索引擎不断调整链接分析技术，加深<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>门槛。<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>ER也必须随着搜索引擎的发展而发展。<br/><br/>以上的研究方法要求全面获取Web资源的使用情况，对于设计真正的Web搜索引擎而言，它是不可行的，所以只是适用于网站内部的信息检索系统中。<br/><br/>与此相反，对于Web搜索引擎，通过添加修正参数的个性化PageRank方法相对较为可行。该方法无需过多地在遍历网页结构时重新定义不同超链的权重分配关系，只需在得到全部网页的简单超链结构关系后，直接通过引入修正参数来体现用户的某种个性化信息。<br/><br/>通过添加修正参数引入个性化信息的网页权重算法在以Kleinberg等设计的HITS算法中就有体现，不像PageRank方法，这个算法对每个网页都分配两个权重值：一个为authority值;另一个为hub值。它们具有一种迭代的定义，即一个好的authority网页是被好的hub网页指向，一个好的hub网页也指向好的authority网页。这种算法主要应用于使用主题爬虫的网页排序方法，还有在受限条件下的Web社区分析等方面这个算法的最初版本没有像PageRank算法那样具有很好的缩放性，而且对于较多网页节点的处理还存在收敛的问题。<br/><br/>这种方法最早在PageRank算法中的用途主要是用于计算主题化PageRank，通过引人代表一定主题的参数向量就可以使PageRank产生主题化倾向。例如，Richardson等通过预处理方法，对不同主题所涉及的网页集合生成不同的PageRank向量，但查询包含上述的一个或者多个主题时，与那些主题有关的预处理PageRank值就可以直接用于运算另外，Haveliwala等使用了另外一种完全不同的方法，他提出了主题相关 PageRank(topic-sensitive PageRank)，这个方法先从Open Directory项目获取主题信息，然而对Open Directory项目的每个类别计算不同的PageRank值，这个PageRank值偏重于该类别内的相关网页。当用户发出查询时，通过识别查询的上下文，相关类别的PageRank值都用于计算结果网页的权重值口引。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=314" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=314</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[SEO教程--网站优化外链的基本策略]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:27:15+08:00</updated>
	  <published>2008-11-16T09:27:15+08:00</published>
		  <summary type="html"><![CDATA[来源：<a target="_blank" href="http://www.chinaz.com/Webbiz/Seo/11124462H008.html" rel="external">中国站长站</a><br/><br/><br/>我们在其它网站做链接可以带来访问量。自从google等主要搜索引擎将网站的链接广泛度作为排名参考的重要因素以后，越多网站链接你，你的网站排名越高。同时，链接的质量也是搜索引擎考虑的重要因素。链接在访问量高的网站比链接在访问量低的网站更有优势。<br/><br/><strong>1、将网站提交到主要的检索目录</strong><br/><br/>确保你的网站登录到免费的Open Directory Project (www.dmoz.com)，这是由人工进行登录审查的网站。该分级目录为所有主要搜索引擎提供它的目录内容供搜索。google很看重你的网站是否在这类重要的网站有链接。 yahoo!是另一个重要的检索目录，需要在上面登录。这也是由人工完成登录审核，因此登录时要非常仔细地按网站提示步骤进行。提示：描述网站的字数最好比规定的最高字数少，不要刚好达到字数极限，以免冗长的文字描述使得网站审核人员删除一些句段。目前商业网站登录yahoo!每年要交9，最好让他们在7 个工作日内就将你的网站登录上去。其它可以考虑登录的检索目录有About.com 和 Business.com。<br/><br/><strong>2、将网站登录到行业站点和专业目录中</strong><br/><br/>有一些检索目录定位于某个行业，如教育或金融业。如果你属于某个贸易协会，该协会集中了诸多会员站点，你可向该协会网站申请加入你的站点，哪怕付费也是应该的，因为这会为你带来许多目标访问者。<br/><br/><strong>3、请求互换链接</strong><br/><br/>寻找一些与你的网站内容互补的站点并向对方要求互换链接。最理想的链接对象是那些与你的网站流量相当的网站。流量太大的网站管理员由于要应付太多要求互换链接的请求，容易将你忽略。小一些的网站也可考虑。互换链接页面要放在在网站比较偏僻的地方，以免将你的网站访问者很快引向他人的站点。找到可以互换链接的网站之后，发一封个性化的Email给对方网站管理员，如果对方没有回复，再打电话试试。<br/><br/><strong>4、发表免费文章，附带站点签名</strong><br/><br/>免费为其它网站的新闻邮件(电子通讯/杂志)写一些专业性文章，文章里用简短的文字附带描述你提供的东西，并请求对方链接你的网站。这是一种有效的病毒营销方法，你的文章将作为成百上千的用户订阅信息发出去，让你的网站一次性获得几百个链接。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=313" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=313</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[SEO教程--目标针对谷歌搜索引擎优化的12个基本步骤]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:24:16+08:00</updated>
	  <published>2008-11-16T09:24:16+08:00</published>
		  <summary type="html"><![CDATA[来源：<a target="_blank" href="http://www.chianz.com/" rel="external">中国站长站</a><br/><br/><br/>根据我的经验，介绍一下怎么才能让自己的站被Google搜索到并且搜索得更多，排名更好。这基本属于<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>的范畴，不过个人Blog的<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>和商业网站的<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>虽然都是<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>，但是侧重点应该有所不同。<br/><br/>我的这个站发布于8月20号，目前Google的抓取和收录情况良好，部分页面，尤其是原创性的长文章页面在Google的搜索结果中表现不错(即使还在 Sandbox)。由于刚刚发布不到一个月，数据还没有更新，因此PageRank还是0，需要等一两个月再看看表现。所以说其实我没有资格来说<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>，不过既然被人找上门来了，就胡扯几句。<br/><br/>至于为什么对自己的Blog做<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>或者做推广?各人看法不同。当然，如果你觉得不需要，那么就不用往下看了。<br/><br/><strong>1. 使用独立域名，自己架设的空间。</strong><br/><br/>保证自己能对页面的控制权，可以进行一些页面优化，关键词优化，添加一些简单而又有用的功能提升排名。如果你不具备自己假设独立域名站点的能力和条件，那么在选择你的Blog服务商的时候，注意以下几点：<br/><br/>1) 不要使用网易博客和搜狐博客作为你的Blog。这两家Blog都使用了<a href="http://www.yaohaixiao.com/default.asp?cateID=4" target="_blank">Ajax</a>技术来构造整个页面，使得搜索引擎几乎无法从页面上抓到任何有用的信息，所以在Googlebot足够智能到能自动执行<a href="http://www.yaohaixiao.com/default.asp?cateID=4" target="_blank">Ajax</a>之前，使用网易博客和搜狐博客就等于自绝于所有搜索引擎——不光是Google。另外，参考之前对搜狐博客和百度空间的分析，如果你想让你的Blog能在除了Google和百度之外其他的搜索引擎上出现，那么不要选择百度空间，否则的话百度空间还是可以的，因为百度对它的支持非常好，排名总在最前面。<br/><br/>2) 尽量使用支持<a href="http://www.yaohaixiao.com/default.asp?cateID=4" target="_blank">Javascript</a>的空间。事实上出于安全考虑，大部分服务商都不在此列，包括百度空间和微软的Live Space，不支持<a href="http://www.yaohaixiao.com/default.asp?cateID=4" target="_blank">Javascript</a>使得一些优化不能进行。<br/><br/>3) 不要选择经常被GFW的国外服务商，例如Blogspot，尽管它的功能非常强大并且被Google很好地整合。除非你人在国外并且完全不考虑国内的读者，否则这些时通时断的服务商显然不被考虑。<br/><br/><strong>2. 保持网站的畅通。</strong><br/><br/>慢一些问题不大，但是如果经常无法访问就是大问题了。如果你的网站托管在国内，一定记住去备案自己的域名，现在风声很紧，不备案的网站随时可能被关闭，连数据一起丢失。不备案是万万不行的，不过这不等于备案就万事大吉了。你的网站托管商或者当地公安部门都可能暂时关闭你的网站，只要有一点点不和谐言论，或者和你托管在同一主机的其他站点有不和谐言论，你也会被波及。因此，如果条件允许，把网站放到境外的服务器上，找一些没有历史污点并且服务还不错的空间。从现在的信息看，放在国外被GFW的概率比放在国内被拿走硬盘的概率要小得多，损失也要小得多。<br/><br/><strong>3. 保证自己网站高质量的内容和经常性的更新。</strong><br/><br/>Google喜欢原创内容而讨厌转载是长期来大家的共识。拥有大量原创独创内容的网站更容易得到高的PageRank。而更新频繁的网站也会得到更多青睐。所以在硬件(域名，空间)达标的情况下，内容是王道。任何时刻任何情况下，好的内容比任何特意的优化都重要得多。<br/><br/><strong>4. 增加外部链接。</strong><br/><br/>尤其是PageRank高的网站上给你的链接，往往会起到意想不到的好作用。这是由PageRank的算法决定的。比如找你的朋友给你做个链接，比如在别人的空间留言时留下自己的地址。当然，不要因此而去动歪脑筋，去做Spam，一旦被发现，可能你的网站直接就废了。<br/><br/><strong>5. 页面的静态化和URL的含义。</strong><br/><br/>对搜索引擎来说，静态化的页面是最友好，最容易被收录的，因此尽量静态化你的页面吧。WordPress和Movable Type都需要较复杂的配置来实现页面静态化，据说Z-Blog相对比较容易不过我没试过。而我的北落师门从一开始的设计，就是以所有页面的静态化为基础的，因此不需要任何配置就可以做到。如果静态化的页面能有一个比较好的名字则更好。搜索引擎也一样，页面URL里提供的关键字也会影响页面的收录。<br/><br/>[/b]6. Tag的使用和站内链接优化。[/b]<br/><br/>文章的Tag非常重要，记得一定要写Tag并且最好把它链接到相应关键字的Tag页面，例如这样：Google。同时，在tag的链接标签上，记得添上rel=&#34;tag&#34;，这会被很多搜索引擎识别，比如Technorati，尽管它被和谐了，但是它仍然毫无争议地是真正的博客搜索老大。Google也明确说了使用Tag有助于它对Blog的评价。站内链接则是自己可以控制的优化方案，除了前面说的Tag之外，还有一些其他的注意点，例如每个网页最多离首页四次点击，等等。 Sitemap是一个很好的解决方案，把它放在你的根目录里吧(然后在首页加个链接)。很多第三方工具都可以制作Sitemap。<br/><br/><strong>7. 更新时自动提交ping信息。</strong><br/><br/>意思就是当文章更新的时候，自动告诉一些服务器你更新了文章，邀请他们来抓取。基本上所有主流的架站工具都提供这个功能或者类似的插件，另外我发现 Live Space也有这个功能，其他Blog服务商是否有此功能没有经过测试。我自己的代码ping了Google的Blogsearch ping server、Technorati ping server和Weblog.com ping server。在我发文之后3分钟内，我就可以用Google Blogsearch搜索到我刚发的文章。事实上这样接受推送更新的服务器很多，不过并没有全部告诉的必要，我觉得Google和Technorari足够了。如果百度有这样的Ping server，我想我也会发送的，可是它没有(所以百度的博客搜索基本就等于百度空间的内部搜索)。<br/><br/><strong>8. 优化页面的代码。</strong><br/><br/>用符合w3c标准的代码，不要用table。Google更喜欢标准代码。无论你的页面结构如何，无论是两列还是三列，内容在左边还是中间还是右边，记住一定在页面源码中把它放到尽量前面(用table就做不到)。选择这样的模版，或者自己写这样的代码。另外，所有的图片加上alt标签，所有的链接，如果有必要的话加上title(和链接文字一样就不用加了)，这样的细节有助于你的网页更加被搜索引擎所理解。<br/><br/><strong>9. 提交网址。</strong><br/><br/>事实上往搜索引擎提交网址的作用已经越来越小，远远不如几年前那么重要了。这里推荐一个：DMOZ。如果你能成功将自己网站提交倒DMOZ上，那么对于你的PageRank会大有好处。<br/><br/><strong>10. 让你的朋友用Google Reader订阅你的feed。</strong><br/><br/>这条看上去很古怪是吧?但是事实是，Google确实把一个Blog在Google Reader中的订阅数作为了一个评价指标，因此，使用Google Reader吧。顺便说一句，同样道理，让朋友们将你的文章收藏到百度搜藏也可以让百度提高对该页面的权重。<br/><br/><strong>11. 使用Google提供的各种小工具。</strong><br/><br/>比如Google Analytics统计工具(强烈推荐)，比如Google Coop站内搜索引擎，当然还有Google Webmasters来随时查看自己的站点在Google的表现。<br/><br/><strong>12. 不要尝试黑帽<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>。</strong><br/><br/>很多网站因为黑帽<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>被永久性咔嚓了。而我们做的，是完全非商业性的，只是用来展示自己表达自己的个人空间而已，何必要去急功近利呢？]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=312" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=312</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[SEO教程--让搜索引擎对你的网站最好友化的七个步骤]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:20:48+08:00</updated>
	  <published>2008-11-16T09:20:48+08:00</published>
		  <summary type="html"><![CDATA[来源：<a target="_blank" href="http://chinaz.com/Webbiz/Seo/111344D42008.html" rel="external">中国站长站</a><br/><br/><br/>搜索引擎最佳化是很多网站的站长们都想要做的事情，但除了号称<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>服务的公司之外，似乎没有太多人有这样的信息,刚好在国外的论坛看到有关如何执行搜索引擎最佳化的文章，就花了点时间把这篇文章吸收消化然后用中文写出来了。<br/><br/><strong>第一个步骤</strong><br/><br/>你得要有一个「网站」，这句话看起来像是句废话，但其实不然，因为「搜索引擎最佳化」的目的是在于提升你网站相关关键词的网络排名，所以第一步你得先要能够吸引搜索引擎到你网站作客，所以如何建构一个SEF(Search Engine Friendly)的网站是第一个关键，SEF的意思是说对搜索引擎友善的意思;因为当搜索引擎在读取你的网站时，他所读取的是你网站上面的原始程序代码，所以你程序代码的撰写是否符合W3C的规范，就会影响搜索引擎在阅读你网站时的顺畅程度了，一个不符合SEF精神撰写的网站，往往会在搜索引擎拜访时回报大量的错误讯息回到负责运算搜索引擎排名的服务器里，如果这个网站在决定你搜索引擎排名的服务器里有一堆的错误讯息被回报时，那这个网站的排名一定也好不到哪里去。<br/><br/>再来，你得要替你的网站撰写一些内容，对部落格而言，就是替这个部落格增加几篇文章。内容的不断增加是持续改善网站/部落格排名的一个重要因素，这个动作应该要持续到你决定不再继续经营这个网站为止。<br/><br/><strong>第二个步骤</strong><br/><br/>当你已经以正确的程序语法撰写这个网站，并同时持续的替这个网站带来新的内容的时候，你该做的事情就是要邀请「搜索引擎机器」人到你的网站泡茶聊天，这样搜索引擎机器人才有机会把你网站的内容回报回去到负责计算排名的服务器去。<br/><br/><strong>第三个步骤</strong><br/><br/>当搜索引擎机器人已经知道你网站的地址以及去拜访过你的网站之后，你就要先试着去搜索引擎上面查查看你的网站是否已经被主要的搜索引擎 (Google、Yahoo、baidu)收录了?一般而言，只要你确定有搜索引擎机器人去你的网站拜访过之后，你的网站应该会在两三个月内被搜索引擎收录进去他们的数据库里面了。<br/><br/><strong>第四个步骤</strong><br/><br/>当你已经确定你的网站被搜索引擎收录之后，你接下来的动作就是去记录你被收录的网页有哪些?知道你到底有哪些网页被搜索引擎收录是一个很重要的动作，因为你无法针对没有被收录的网页进行所谓搜索引擎排名最佳化的动作。这个时后可以先不要去烦恼你那些还没有被收录的网页，一般而言除非那些网页被判定为恶意欺骗搜索引擎，要不然被收录是早晚的事情。<br/><br/><strong>第五个步骤</strong><br/><br/>针对你已经被搜索引擎收录的网页进行排名优化，接下来的步骤会比较繁杂，首先你要先把你个别网页的关键词定义出来(请参考关键词定义的方法这篇文章)，当你定义出这个网页的关键词之后，你可以到搜索引擎上打上你这个网页的网址和你所定义的关键词，对这两个信息做交集查询，如果查询的结果有出现你刚刚键入的网站和关键词时，那恭喜你，这个关键词被搜索引擎认定和你这个网页具有关联性，也就是说你这个网页的内容里面是包含这个关键词的。相反的，如果查询的结果并没有出现这个网页，那你得回到前面定义网页关键词的步骤重新来过，一直到出现正确的结果为止。<br/><br/><strong>第六个步骤</strong><br/><br/>先找个地方把你刚刚查询的网页和相对应的关键词先纪录下来，这样可以确保你不会忘记这个网页的关键词是什么。接着，就是去看看你这个网页在搜索引擎中相对应于这个关键词的排名的时候了，查询的方法很简单(但也很耗时… )。先打开你要查询排名的搜索引擎(例如你想要知道在雅虎奇摩里面的排名)，在搜寻框里面键入你刚刚替这个网站定义的关键词，这样搜索引擎显示出来的结果就是和这个关键词有关联性的网站，排名越前面，代表搜索引擎认为和这个关键词的关联性越高，一般而言，排名在前二十名的网页，才会有比较大的机会吸引访客的进入，换言之，排在二十名之后的网页，就像坐落在深山峻岭中的LV旗舰店一样，是不会引起访客的注意的。<br/><br/><strong>第七个步骤</strong><br/><br/>延续第六个步骤，你要找出你这个网页在这个关键词查询结果的排名，这样你才能观察你上下左右的对手，进而去分析怎样改善这个网页的搜索引擎排名结果，你可以参考怎样知道网页在关键词查询结果的排名这篇文章来知道怎样找出自己的排名在第几?当你找出排名之后，你就可以真正的开始进行搜索引擎排名最佳化的动作了。<br/><br/>结论，搜索引擎最排名最佳化的技术，其实说穿了并不难，真正的困难度在于执行上有很多繁琐的步骤，再加上你不见得可以立即看到成效(因为等搜索引擎更新排名也是需要时间的)，所以才会带给外界一种神秘的面纱。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=311" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=311</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[SEO教程--多个关键词排名总是一升一降的问题分析]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:17:38+08:00</updated>
	  <published>2008-11-16T09:17:38+08:00</published>
		  <summary type="html"><![CDATA[作者：杨振秋<br/>来源：<a href="http://www.gangguanhb.com/" target="_blank" rel="external">http://www.gangguanhb.com/</a><br/><br/><br/>在网站优化时，经常会遇到客户要求优化两个甚至两个以上关键词的情况。不少优化人员都觉得这要比只优化一个关键词难很多。但是为了养家糊口，再难的单也要接不是。好了，时间不多，等下还要忙其他的优化工作，就赶紧切入正题吧。<br/><br/>在一些<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>论坛上经常看到有人会对优化的多个关键词，在排名上总是会出现一个上升，另外一个则90%会下降的问题感到不解。看了看回复解答的人的解释，居然如出一辙的都认为是百度(这个问题主要是在百度上出现，所以主讲百度)的问题，说百度排名出现浮动很正常。<br/><br/>但我却不这么认为，如果一个关键词的排名上升，另一个关键词的排名就下降的情况出现的频率比较少，将原因归结为“正常”倒也说得过去。但如果这种情况经常性出现，而且还有不少人遇到，那就明显不正常了。我自己对此种情况的分析如下。<br/><br/>现在假设我们有一个网站要优化，其中客户要求优化的关键词为“无缝管”和“钻井管”。我认为，在你的优化工作中随着有关“无缝管”关键词的内容的增加，以及外部链接中以“无缝管”为锚文本的链接的增加，百度就会以”无缝管”关键词做为你网站的主关键词，那么另一个关键词”钻井管”就被认为副关键词。关键词“无缝管”的权重自然大于“钻井管”关键词。<br/><br/>相应地，百度就会认为你的网站主要涉及的是与“无缝管”关键词有关的内容，那百度就会为你的网站在“无缝管”行业中打分以确定你的地位，从而确定你的排名。优化工作仍然在继续，当不知不觉中有关“钻井管”关键词的内容的增加，以及外部链接中以“钻井管”为锚文本的链接的增加逐渐多余“无缝管”的时，百度则又会认为“钻井管”关键词为你网站的主关键词，“无缝管”与“钻井管”的权重进行互调。也因为涉及“钻井管”的内容及外链等东西都增加了，所以“钻井管”的排名自然会上升。而即使涉及“无缝管”的外链与内容也比以前有所增加，但因其“总量”少于“钻井管”，且其权重也下降了，所以其排名会出现下降，也就是说“无缝管”关键词排名的下降主要是因其权重下降因其的。<br/><br/>当然，也有不少人会说这两个关键此我都是同时优化的，在内容增加，外链增加上，两个关键词的数量都是一样的，不可能一个多一个少。其实这只是你所认为的，就算内容同样多，但收录情况却未必一样，即使收录数量一样多 ，但搜索引擎认为是有效外链的数量却又未必一样多。(gangguanhb.com)]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=310" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=310</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[SEO教程--夯实基础，网站搜索引擎优化菜鸟级别教程]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=17" label="其他内容" /> 
	  <updated>2008-11-16T09:12:05+08:00</updated>
	  <published>2008-11-16T09:12:05+08:00</published>
		  <summary type="html"><![CDATA[来源:<a target="_blank" href="http://www.chinaz.com" rel="external">中国站长站</a><br/><br/><br/><a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>翻译成中文就是“搜索引擎优化”，搜索引擎是除电子邮件以外被用得最多的网络行为方式。本文列举了一些网站的搜索引擎优化菜鸟级别的教程。<br/><br/><strong>网站内容是搜索引擎优化的第一要素</strong><br/><br/>1. 大量的原创内容能够帮助你在客户的心里建立良好的信誉和权威的地位。<br/><br/>2. 其他的站长会自动的链接到你的网站。<br/><br/><strong>判定文章原始出处的方法：</strong><br/><br/>1. 网页PR值。<br/><br/>2. 网页第一次被收录的时间。<br/><br/>3. 域名注册时间。(百度似乎认为域名比较老的就是原创)<br/><br/>4. 网站的权威度。<br/><br/><strong>要害词的选择：</strong><br/><br/>1. 要害词不要太宽泛<br/><br/>2. 主打要害词也不适于太长太非凡，例如公司名称(知名品牌出外)<br/><br/>3. 站在用户角度思考，专业名词用户不会搜索，例如<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a><br/><br/>4. 最有效率的要害词就是那些竞争网页最少，同时被用户搜索次数最多的词。<br/><br/>5. 和你的网站要相关<br/><br/><strong>职业<a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>应该学习的知识：</strong><br/><br/>1. 市场营销 + 网页制作 + 简单的网站程序编写 + <a href="http://www.yaohaixiao.com/default.asp?cateID=25" target="_blank">SEO</a>技术<br/><br/>2. 项目组织和协调 + 关注搜索引擎优化技术的新发展 + 写作能力<br/><br/><strong>怎样治疗网站内容缺乏症：</strong><br/><br/>1. 从产品历史和沿革出发<br/><br/>2. 从制造、发明产品的人出发<br/><br/>3. 从原材料出发<br/><br/>4. 从客户出发<br/><br/>5. 从本行业出发<br/><br/>6. 从产品用途出发<br/><br/>7. 从产品技术出发<br/><br/><strong>网站被惩罚或被封该怎么办：</strong><br/><br/>1. 首先确定你的网站是完全被封，还是只是排名下降。直接搜索一下域名或URL;用site：指令查一下;用网页上某一句独特的话搜索一下(例如版权信息);<br/><br/>2. 检查服务器设置、robots.txt文件、网站是否过度优化(过度优化现在往往是排名被惩罚的重要原因)。<br/><br/>3. 是否有可疑的页面转向?有大量交叉链接?链接向其他有作弊嫌疑的网站?<br/><br/>4. 是否被若为复制内容网页?<br/><br/>5. 是否用了隐藏网页?大量垃圾链接?<br/><br/>6. 其他作弊手段;<br/><br/><strong>高质量的外部链接来自：(你可以反过来思考，不包括的哪些)</strong><br/><br/>1. 开放目录;<br/><br/>2. 其他站对你的新闻介绍;<br/><br/>3. 权威网站的商业链接;<br/><br/><strong>如何写TITLE：</strong><br/><br/>1. 每个页面要不一样，并且符合页面内容;<br/><br/>2. 吸引人，排在搜索结果第一页第一屏，客户点哪个就看标题了;<br/><br/>3. 标题标签中应该含有要害词，并且顺口;<br/><br/>4. 普遍TITLE结构：文章名 - 分类名 - 网站名;例如：胎教音乐下载 – 胎教方法 – 妈妈帮<br/><br/>5. 别堆砌要害字。<br/><br/><strong>搜索引擎对“导入链接”的分析可能包含：</strong><br/><br/>1. 导入链接数目<br/><br/>2. 导入链接本身的重要性，也就是链接向你的网页本身的重要性<br/><br/>3. (这两点也就形成了Google PR，但后面的这些因素都和PR没有直接关系。)<br/><br/>4. 反向链接增加的速度<br/><br/>5. 反向链接所在网站本身的内容主题<br/><br/>6. 反向链接所在页的内容是否相关<br/><br/>7. 反向链接的链接锚文字<br/><br/>8. 反向链接锚文字前后四周的文字<br/><br/>9. 链接在页面的位置<br/><br/>10. 反向链接所在的域名年龄<br/><br/>11. 反向链接所在的域名是否曾经转手<br/><br/>12. 反向链接所在页第一次被收录的日期<br/><br/>13. 反向链接所在页页面内容是否曾经有变化?有什么样的变化?<br/><br/>14. 反向链接第一次出现在页面上是什么时候15. 链接文字是否曾经变化?变化是什么?<br/><br/>16. 反向链接所在页还链接向哪些其他网站?这些其他网站内容是否相关?质量怎么样?<br/><br/>17. 反向链接是否有垃圾链接嫌疑?比如来自论坛签名，博客等地方。<br/><br/>18. 链接点击率19. 用户点击链接后在你的网站停留多长时间<br/><br/><strong>反向链接一般原则：</strong><br/><br/>1. 反向链接的锚文字(链接文字)应该多样化;<br/><br/>2. 链接应该来自相关网页;<br/><br/>3. 链接在网页不同的位置;<br/><br/>4. 逐步自然增长;<br/><br/>5. 反向链接应该来自不同PR的网页;<br/><br/>6. 来自好的邻居;<br/><br/>7. 链接应该来自不同的IP地址;<br/><br/>8. 来自新旧网站的链接都有;<br/><br/>9. 优质交换链接或友情链接;<br/><br/>10. 链接到内容网页;千万不要把所有链接都指向你的主页;<br/><br/>11. 链接向你的网页是不是还链接向其他的不好的网页<br/><br/><strong>要害字的选择步骤：</strong><br/><br/>1. 列出大量要害词：自己想、问朋友、看对手、用工具;<br/><br/>2. 要害词竞争程度：总相关网页数;竞价广告价格;<br/><br/>3. 要害字被搜索次数;<br/><br/>4. 计算要害词效能;<br/><br/>5. 确定要害字;<br/><br/><strong>针对要害词进行网页优化：</strong><br/><br/>1. 要害词密度<br/><br/>2. HTML标签<br/><br/>3. 要害词在网页正文中：正文标题、开头、H1～H3、加粗(黑体)、斜体<br/><br/>4. URL中的要害词<br/><br/>5. 要害词出现在链接中<br/><br/>6. 注重优化自然性，防止过度优化。<br/><br/><strong>URL优化规则：(在选择CMS或BLOG程序时需要考虑)</strong><br/><br/>1. 选个好域名，和网站主题相关，例如中国站长站（chinaz.com），一看就知道是一个站长网站;<br/><br/>2. 静态化，别有“ ? %26amp; %”等;<br/><br/>3. 文件名包含内容相关的要害字<br/><br/>4. 别太长<br/><br/>5. 全部用小写，因为Unix/Linux服务器大小写字母是不同处理;；<br/><br/><strong>提高域名信任度的几个简单方法：</strong><br/><br/>1. 网站要有隐私权政策，非凡是需要用户注册的网站;<br/><br/>2. 提供完整的联系方法，地址、电话、邮编、EMAIL、QQ、MSN等等;<br/><br/>3. 页面数量;<br/><br/>4. 与行业内权威网站的链接;<br/><br/>5. 域名一次注册N年，而不是每年续费;<br/><br/>6. 拥有独立IP地址;服务器反应快速;<br/><br/>7. 没有死链接、无效链接、假链接(该有链接的地方缺没有)<br/><br/>8. 网页HTML代码经过W3C验证;<br/><br/>9. “关于我们”写的具体。<br/><br/><strong>网站健康检查：</strong><br/><br/>1. 首先看域名Whois信息，注重域名第一次注册的时间，中间有没有注册人转手;<br/><br/>2. 检查网站DNS设置是否正确，是否有多个域名。<br/><br/>3. URL是否静态化。<br/><br/>4. 收录情况怎样?<br/><br/>5. 是否有作弊行为：隐藏文字、群发链接等;<br/><br/>6. 页面设计是否漂亮，规范。<br/><br/>7. 网站所在的IP地址上还有哪些网站，收录情况，外部链接情况，外观感觉怎样;<br/><br/><strong>站内链接的优化：</strong><br/><br/>1. 建立规范的网站地图;<br/><br/>2. 每个网页最多离首页四次点击;<br/><br/>3. 使用文字导航<br/><br/>4. 链接文字包含要害字;<br/><br/>5. 网页的互相链接，使用“相关文章”“推荐文章”“随机文章”等功能;<br/><br/><strong>新站点怎样寻找外部链接：</strong><br/><br/>1. 新站点开通三个月以后，再开始寻找链接;因为收录、PR都稳定了;<br/><br/>2. 登录分类目录;直接搜索“分类信息”或者“黄页”等可以搜到很多这样的网站 ，我的科迪络互联传媒很轻易就加入了。<br/><br/>3. 写博客，发布有吸引力的文章，请朋友转贴;<br/><br/>4. 网站初期从非商业性开始，因为商业网站相对难得到链接;<br/><br/>5. 与同类网站友情链接;<br/><br/><strong>需要知道竞争对手网站的哪些情况：</strong><br/><br/>1. 这些网站规模有多大，网站本身有多少页?<br/><br/>2. 收录了多少页?<br/><br/>3. 这些网站的栏目设置?<br/><br/>4. 内容是原创为主，还是采集的?<br/><br/>5. 网站PR值?<br/><br/>6. 域名注册时间?<br/><br/>7. 网页要害词密度?<br/><br/>8. 要害词出现的位置?<br/><br/>9. 有没有一定的规律可以学习?<br/><br/>10. 在雅虎查一下这些网站的外部链接有多少?<br/><br/>11. 外部链接来自于什么地方，质量如何?<br/><br/>12. 是大量的友情链接，垃圾链接?还是来自新闻门户?<br/><br/><strong>百度排名观察：</strong><br/><br/>1. 百度蜘蛛极为活跃。<br/><br/>2. 似乎更注重页面内的因素。<br/><br/>3. 没有类似于Google沙盒效应的因素。<br/><br/>4. 目标要害词应该完整匹配地出现在页面中。<br/><br/>5. 比较少考虑整个网站的主题。<br/><br/>6. 过度的优化网页并不能在百度搜索中得到好的排名。<br/><br/>7. 相较于Google排名来说比较简单。只要你的网站符合最基本的用户友好原则和搜索引擎优化原则，就应该会得到相当不错的排名。<br/><br/><strong>网上创业建议：</strong><br/><br/>1. 先别辞职<br/><br/>2. 从自己的爱好出发<br/><br/>3. 先找准目标市场再谈其他<br/><br/>4. 不要期望过高<br/><br/>5. 花时间学习最基本的技术<br/><br/>6. 要努力，要坚持。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=309" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=309</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Javascript教程--[翻译]JavaScript中对象的层次与继承]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=4" label="Javascript" /> 
	  <updated>2008-11-15T14:45:02+08:00</updated>
	  <published>2008-11-15T14:45:02+08:00</published>
		  <summary type="html"><![CDATA[版权所有：Copyright 1997 Netscape Communications Corporation<br/>原文链接：<a target="_blank" href="http://www.cs.rit.edu/%7Eatk/JavaScri&#112;t/manuals/jsobj/" rel="external">Object Hierarchy and&nbsp;&nbsp;Inheritance in JavaScript</a><br/>最后更新：1997年12月18日<br/><br/>翻译日期：2008年11月11日<br/>文章翻译：<a target="_blank" href="http://www.cainiao8.com" rel="external">chenzhe</a><br/>翻译注解：<strong>object hierarchy[b]译为[b]对象层次</strong>;<strong>constructor</strong>译为<strong>构造器</strong>;<strong>constructor function</strong>和<strong>constructor method</strong>译为<strong>构造函数</strong>;此外，本文中所有涉及__proto__属性的代码适用于FireFox和Chrome，不适用于IE，其它浏览器未测试。<br/><br/>以类为基础的面向对象语言，比如Java和C++，都是建立在两种不同的实体之上：类与实例。一个类定义了某个物体集合的所有属性，而这些属性能够描述这个物体集合的特性（可以想想Java里的方法和域，或者是C++中的成员，把它们当作属性）。类是抽象的事物，而不是它所描述的物体集合中的某一特定的成员。举个例子，Employee（雇员）类可以代表所有的雇员。然而一个实例（<strong>instance</strong>）则是一个类的实例化（instantiation）；也就是说，类的一个成员。还是举例来说明，Victoria就可以是Employee类的的一个实例，代表雇员中的一个特定个体。一个实例和它的父类有完全相同的属性（不多，也不少）。<br/><br/>以原型为基础的语言，比如说JavaSctipt，并没有这个区别（类和实例的区别）。它只有对象。以原型为基础的语言中有<strong>原型对象（prototypical object）</strong>这样一个概念，它被当作模板来使用，一个新对象将会从这个模板中获得初始的属性。任何物体都可以随时给自己设置特性，可能是当您创建它的时候，甚至也可以是在运行时。此外，任何对象都可以被关联为另一个对象的<strong>原型</strong>，以允许第二个对象分享的第一个对象的属性。<br/><br/>在以类为基础的语言中，你需要在一个单独的<strong>类定义（class definition）</strong>中定义类。在这一定义中，您可以指定特殊的方法，即所谓的<strong>构造器（constructors）</strong>，构造器用来创建该类的实例。构造器可以给实例的属性设置初始值，并在合适的时候执行其他的流程。你可以使用new操作符来配合构造器创建类的实例。<br/><br/>JavaScript也遵从相似的模式，但是并没有将构造器区别出来的类定义。相反，你要定义一个构造器函数（constructor function）来创建有若干初始属性和属性值的对象。任何JavaScript函数都可以被用来当作构造器。你可以使用new操作符和构造函数来创建一个新对象。<br/><br/>在以类为基础的语言中，你通过类的定义来实现类的层次。在类定义中，你可以指定新的类是某个已存在类的子类（subclass）。子类继承超类（superclass）的所有属性，而且还可以额外添加新的属性，或是修改继承的属性。比如说，我们假设Employee类只包含 nameanddept属性（姓名和部门），Manager（经理）是Employee类的子类，它添加了reports（报告）属性。在这种情况下，一个Manager类的实例会有所有的三个属性：name,dept, 和reports。<br/>JavaScript允许你将原型对象与任何构造器函数相关联，以此实现继承机制。所以，你完全可以创建和上面一模一样的Employee- Manager实例，但是要使用稍有不同的词汇。首先你要定义Employee构造函数，指定name和dept属性。然后，你定义Manager构造函数，设置reports属性。最后，你把Employee对象设置为Manager构造函数的prototype。之后，当你创建一个新的Manager 的时候，它会从Employee对象继承name和dept属性。<br/><br/>在以类为基础的语言中，在典型情况下，你在编译时创建class，之后你就可以在运行时或者是编译时将class实例化。你不能在定义class之后改变对象属性的个数或者是种类。然而，在JavaScript中，你可以在运行时向任何对象添加或者删除属性。如果你给一个对象添加属性，而这个对象又是某些对象的prototype，那些以它为prototype的对象也将获得新的属性。<br/><br/>表1是对这些区别的摘要。这篇文章的剩下的部分会描述使用JavaScript构造器和prototype来创建对象层次的细节，并且对比在Java中完成相同工作的方法。<br/><br/><br/><strong>表 1基于类（Java）与基于原型（JavaScript）的对象系统的对比</strong><br/><br/>==================================================================================================<br/><strong>基于类（Java）</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>基于原型（JavaScript）</strong> <br/>==================================================================================================<br/>类和实例是不同的实体。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所有的对象都是实例。<br/>使用类定义来定义类；使用构造函数来将类实例化。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用构造函数定义，并且创建一些列对象。<br/>使用new操作符来创建一个新的对象。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一样。<br/>使用类定义来定义已存在类的子类，以此来创建对象层次。 通过将一个对象设置为关联到某个构造函数的原型，从而创建对象层次。<br/>通过类链（class chain）继承属性。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过原型链继承属性。<br/>类定义设置类的所有实例的所有属性。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 构造函数或者是原型指定了一系列原始（initial）属性。<br/>不能再运行时动态添加新的属性。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以动态地向个别对象或者一个对象集合添加或删除属性。<br/><br/><strong>Employee雇员实例</strong><br/><br/>本文剩下部分的工作就是实现图1中简单的employee雇员层次。<br/><br/><div align="center"><strong>一个简单的对象层次</strong></div><br/><div align="center"><img src="http://www.yaohaixiao.com/images/cc-1.png" border="0" alt=""/></div><br/><div align="center">图 1</div><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;* Employee有name属性（默认值为空字符串）和dept属性（默认值&#34;general&#34;）。<br/>&nbsp;&nbsp;&nbsp;&nbsp;* Manager以Employee为基础。它添加了一个reports属性（默认值是空的数组，我们意在让其成为一个值为Employee对象的数组）。<br/>&nbsp;&nbsp;&nbsp;&nbsp;* WorkerBee同样以Employee为基础。它添加了projects属性（默认值是空的数组，我们意在让其成为一个值为字符串的数组）<br/>&nbsp;&nbsp;&nbsp;&nbsp;* SalesPerson以WorkerBee为基础。它添加了quota（配额）属性（默认值100）。它还将dept属性的值覆盖为&#34;sales&#34;，表明所有的销售人员都在同一个部门。<br/>&nbsp;&nbsp;&nbsp;&nbsp;* Engineer以WorkerBee为基础。它添加了machine（机器）属性（默认值为空字符串）。它同样将dept属性的值覆盖为&#34; engineering &#34;。<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/><strong>创建层次</strong><br/><br/>要定义合适的构造函数以实现Employee层次，你有多种方式可以使用。如何选择在很大程度上取决于你想要在你的应用（application）中能够做些什么事情。我们稍后再来讨论这个问题。<br/><br/>就现在而言，我们使用非常简单的（相对来讲也是灵活的）定义，这仅仅是为了看看继承是如何工作的。在这些定义中，你不能在新创建一个对象的时候设置任何属性值。新创建的对象仅仅是取得默认值，你可以稍后再修改这些属性。图2展示了这种简单定义的层次。<br/>在实际的应用中，你可能定义允许你在创建对象的同时指定属性值的构造函数。我们会在后面的&#34;更加灵活的构造函数&#34;部分介绍实现方法。现在，这些简单的定义可以让我们观察到继承是如何发生的。<br/><br/><div align="center"><strong>以上定义看起来的样子What the definitions look like</strong></div><br/><div align="center"><img src="http://www.yaohaixiao.com/images/cc-2.png" border="0" alt=""/></div><br/><div align="center">图 2</div> <br/><br/>如下，Java和JavaScript简单的Employee定义非常相似。唯一的不同就是在Java中，你需要指定属性的类型，而在JavaScript中不需要，而且你需要给Java类定义一个明确的（explicit，显式）的构造函数。<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>javascript的方法<br/><br/>function Employee () {<br/>&nbsp;&nbsp;this.name = &#34;&#34;;<br/>&nbsp;&nbsp;this.dept = &#34;general&#34;;<br/>}<br/></div></div><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>java的方法<br/><br/>public class Employee {<br/>&nbsp;&nbsp;public String name;<br/>&nbsp;&nbsp;public String dept;<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;public Employee () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = &#34;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.dept = &#34;general&#34;;<br/>&nbsp;&nbsp;}<br/>}<br/></div></div><br/><br/>Manager 与 WorkerBee 的定义显示了，在构建继承链条中更高层对象的方式中的不同。在JavaScript中，你将一个原型实例设置为构造函数的prototype属性。你可以在定义了构造器之后的任何时间来完成这项工作。在Java中，你在类定义中指定超类（superclass）。你不能在类定义之外改变超类。<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>javascript的方法<br/><br/>function Manager () {<br/>&nbsp;&nbsp;this.reports = [];<br/>}<br/>Manager.prototype = new Employee;function WorkerBee () {<br/>&nbsp;&nbsp;this.projects = [];<br/>}<br/>WorkerBee.prototype = new Employee;<br/></div></div><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>java的方法<br/><br/>public class Manager extends Employee {<br/>&nbsp;&nbsp;public Employee[] reports;<br/>&nbsp;&nbsp;public Manager () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.reports = new Employee[0];<br/>&nbsp;&nbsp;}<br/>}<br/>public class WorkerBee extends Employee {<br/>&nbsp;&nbsp;public String[] projects;<br/>&nbsp;&nbsp;public WorkerBee () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.projects = new String[0];<br/>&nbsp;&nbsp;}<br/>}<br/></div></div><br/><br/>Engineer和SalesPerson的定义从WorkerBee继承下来的对象，自然也是从Employee继承而来。这些类型的对象拥有所有在链条上游对象（objects above it in the chain）的属性<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>javascript的方法<br/><br/>function SalesPerson () {<br/>&nbsp;&nbsp;this.dept = &#34;sales&#34;;<br/>&nbsp;&nbsp;this.quota = 100;<br/>}<br/>SalesPerson.prototype = new WorkerBee;<br/><br/>function Engineer () {<br/>&nbsp;&nbsp;this.dept = &#34;engineering&#34;;<br/>&nbsp;&nbsp;this.machine = &#34;&#34;;<br/>}<br/>Engineer.prototype = new WorkerBee;<br/></div></div><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>java的方法<br/><br/>public class SalesPerson extends WorkerBee {<br/>&nbsp;&nbsp;public double quota;<br/>&nbsp;&nbsp;public SalesPerson () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.dept = &#34;sales&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.quota = 100.0;<br/>&nbsp;&nbsp;}<br/>}<br/>public class Engineer extends WorkerBee {<br/>&nbsp;&nbsp;public String machine;<br/>&nbsp;&nbsp;public Engineer () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.dept = &#34;engineering&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.machine = &#34;&#34;;<br/>&nbsp;&nbsp;}<br/>}<br/></div></div><br/><br/>使用这些定义，你可以创建这些对象的实例，而这些实例会获得属性的默认值。图3展示了使用以上JavaScript定义新对象和这些新对象的属性值。<br/><br/><strong>注意：</strong>正如之前描述的，<strong>实例（instance）</strong>这个词汇在基于类的语言中有特殊的技术含义。在这些语言中，一个实例是一个类的个体成员，是从根本上不同于类的。在JavaScript中，“实例”并没有这个技术含义，因为JavaScript没有类和实例的区别。以后再谈论JavaScript的时候，“实例”可以被用来非正式地指代用某个特定构造函数创建的一个对象。所以，在这个例子中，你可以非正式地说jane是Engineer类的一个实例。相似的，尽管父亲（<strong>parent</strong>）、儿子（<strong>child</strong>）、祖先（<strong>ancestor</strong>）、后代（<strong>descendant</strong>）这些词汇在JavaScript中同样没有正式的意义，我们仍然可以非正式地使用他们来指代原型链中位置或高或低的对象。<br/><br/><div align="center"><strong>使用简单的定义创建对象</strong></div><br/><div align="center"><img src="http://www.yaohaixiao.com/images/cc-3.png" border="0" alt=""/></div><br/><div align="center">图3</div> <br/><br/><strong>对象的属性</strong><br/><br/>本部分讨论在原型链中，对象是如何从其他对象中继承属性，以及当你在运行时添加一个属性的时候会发生什么事情。<br/><br/><strong>继承属性</strong><br/><br/>假设你像图3中一样定义了一个WorkerBee的mark 对象，语句如下：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>mark = new&nbsp;&nbsp;WorkerBee;<br/></div></div><br/><br/>当JavaScript看到new操作符，它就创建一个新的通用对象，并且将这个新对象作为this的this关键字的值传递给WorkerBee构造函数。构造函数显式地设置projects属性的值。并且它会将WorkerBee.prototype的值设置为内部的 __proto__属性的值。（那个属性在两侧分别由两个下划线。）当这些属性被设置完之后，JavaScript将新对象返回，而赋值语句就会将 mark变量设置为那个对象。<br/><br/>这个过程并没有显式地给mark对象从原型链中继承的属性赋值（局部变量）。当你请求一个属性值的时候，JavaScript首先检查这个值在对象中是否存在。如果存在，就返回那个值。如果值在本地不存在， JavaScript会检查原型链（使用 __proto__）。如果在原型链里的某个对象有该属性的值，就返回那个值。如果没有找到这个属性，JavaScript会说对象没有这个属性。由此来说，mark对象有如下几个属性和值：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>mark.name =&nbsp;&nbsp;&#34;&#34;;<br/>mark.dept = &#34;general&#34;;<br/>mark.projects =&nbsp;&nbsp;[];<br/></div></div><br/><br/>mark对象从mark.__proto__中的原型对象中继承了name和dept属性的值。它的projects属性被 WorkerBee构造器赋予了本地的值。简单地说，这给了你在JavaScript中对属性和属性值的继承。这个过程的一些细节将会在&#34;又见属性继承&#34; 部分讨论。<br/><br/>因为这些构造器不让你给特定的实例指定值，这些信息都是通用的。属性值都是默认值，由所有的WorkerBee新建对象所分享。你当然可以改变任何属性的值。所以，你可以像下面这样给mark一些指定的信息：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>mark.name =&nbsp;&nbsp;&#34;Doe, Mark&#34;;<br/>mark.dept = &#34;admin&#34;;<br/>mark.projects&nbsp;&nbsp;= [&#34;navigator&#34;];<br/></div></div><br/><br/><strong>添加属性</strong><br/><br/>在JavaScript中，你可以在运行时给任何对象添加属性。并不限于使用构造器提供的属性。要给单独的对象添加特定的属性，你只需要简单地给对象赋值就可以了，像这样：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>mark.bonus = 3000;<br/></div></div><br/><br/>现在，mark对象就有一个额外的属性了，任何其他的WorkerBee都没有这个属性。<br/><br/>如果你给一个对象添加了新的属性，而它又被一个构造器作为原型，你就为所有从该原型继承属性的对象添加了那个属性。举例来说，你可以给所有的雇员（employees）添加一个specialty属性，就使用下面的语句：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>Employee.prototype.specialty&nbsp;&nbsp;= &#34;none&#34;;<br/></div></div><br/><br/>一旦JavaScript执行到这条语句，mark对象也会拥有这个specialty属性，且属性值为“none”。图4展示了向 Employee的原型添加这个属性，并且在Engineer原型中覆盖它。<br/><br/><div align="center"><strong>添加属性</strong></div><br/><div align="center"><img src="http://www.yaohaixiao.com/images/cc-4.png" border="0" alt=""/></div><br/><div align="center">图 4</div> <br/><br/><strong>更灵活的构造器</strong><br/><br/>至今为止，我们使用的构造函数都不允许你在创建实例的时候指定属性值。就像在Java中一样，你可以给构造器提供参数来初始化实例的属性值。图5展示了实现的方法。<br/><br/><div align="center"><strong>在构造器内设置属性，take 1</strong></div><br/><div align="center"><img src="http://www.yaohaixiao.com/images/cc-5.png" border="0" alt=""/></div><br/><div align="center">图 5</div> <br/><br/>下面是Java和JavaScript 对这些对象的定义。<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>JavaScript 的方法<br/><br/>function Employee (name, dept) {<br/>&nbsp;&nbsp;this.name = name || &#34;&#34;;<br/>&nbsp;&nbsp;this.dept = dept || &#34;general&#34;;<br/>}<br/><br/>function WorkerBee (projs) {<br/>&nbsp;&nbsp;this.projects = projs || [];<br/>}<br/>WorkerBee.prototype = new Employee;<br/><br/>function WorkerBee (projs) {<br/>&nbsp;&nbsp;this.projects = projs || [];<br/>}<br/>WorkerBee.prototype = new Employee;<br/><br/>function Engineer (mach) {<br/>&nbsp;&nbsp;this.dept = &#34;engineering&#34;;<br/>&nbsp;&nbsp;this.machine = mach || &#34;&#34;;<br/>}<br/>Engineer.prototype = new WorkerBee;<br/></div></div><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>Java 的方法<br/><br/>public class Employee {<br/>&nbsp;&nbsp;public String name;<br/>&nbsp;&nbsp;public String dept;<br/>&nbsp;&nbsp;public Employee () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this(&#34;&#34;, &#34;general&#34;);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public Employee (name) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this(name, &#34;general&#34;);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public Employee (name, dept) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.dept = dept;<br/>&nbsp;&nbsp;}<br/>}<br/><br/>public class WorkerBee extends Employee {<br/>&nbsp;&nbsp;public String[] projects;<br/>&nbsp;&nbsp;public WorkerBee () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this(new String[0]);<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public WorkerBee (String[] projs) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.projects = projs;<br/>&nbsp;&nbsp;}<br/>}<br/><br/>public class Engineer extends WorkerBee {<br/>&nbsp;&nbsp;public String machine;<br/>&nbsp;&nbsp;public WorkerBee () {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.dept = &#34;engineering&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.machine = &#34;&#34;;<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;public WorkerBee (mach) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.dept = &#34;engineering&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.machine = mach;<br/>&nbsp;&nbsp;}<br/>}<br/></div></div><br/><br/>这些JavaScript定义使用一种特殊的风格(idiom)来设置默认值。<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">this.name =&nbsp;&nbsp;name || &#34;&#34;;</div></div><br/><br/>JavaScript的逻辑或操作符(||)先计算第一个参数的值。如果该参数转换为true，操作符就将它返回。否则，或操作符返回第二个参数。因此，这行代码尝试着看看name是否有满意的值。如果有，将this.name的值设置为这个值。否则，它将this.name的值设置为空字符换。本篇文章都会使用这种简洁的风格；然而，第一次看到可能会有一些令人迷惑。<br/><br/>有了这些定义，当你创建任何对象的实例时，你都可以给本地定义的属性设定值了。就像在图5中展示的，你可以使用这个语句来创建一个新的Engineer：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>jane = new&nbsp;&nbsp;Engineer(&#34;belau&#34;);<br/></div></div><br/><br/>现在Jane的属性如下:<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>jane.name ==&nbsp;&nbsp;&#34;&#34;;<br/>jane.dept == &#34;general&#34;;<br/>jane.projects&nbsp;&nbsp;== [];<br/>jane.machine == &#34;belau&#34;<br/></div></div><br/><br/>需要注意的是，使用这个定义，你不能给name等继承的属性指定初始值。如果你想要在JavaScript中给继承的属性设定初始值，你需要再给构造函数多添加一些代码。<br/><br/>到目前为止，构造函数已经创建了一个通用的对象，然后再给新对象指定本地的属性和值。你可以给构造器添加更多的属性，只要调用原型链中更高位置上的构造函数就可以做到这点。图 6展示了这些新的定义。<br/><br/><div align="center"><strong>在构造器内指定属性，take 2</strong></div><br/><div align="center"><img src="http://www.yaohaixiao.com/images/cc-6.png" border="0" alt=""/></div><br/>[align=center]图 6[/b] <br/><br/>让我们详细地看看这些定义。下面就是Engineer类的构造器的新定义。<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;Engineer (name, projs, mach) {<br/>this.base = WorkerBee;<br/>this.base(name, &#34;engineering&#34;, projs);<br/>this.projects&nbsp;&nbsp;= mach || &#34;&#34;;<br/>}<br/></div></div><br/><br/>假设我们像下面这样创建Engineer对象：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>jane = new&nbsp;&nbsp;Engineer(&#34;Doe, Jane&#34;, [&#34;navigator&#34;,&nbsp;&nbsp;&#34;javascript&#34;], &#34;belau&#34;);<br/></div></div><br/><br/>JavaScript会执行如下步骤：<br/><br/>1.首先，new操作符创建一个通用的的对象，然后设置它的__proto__属性为Engineer.prototype。<br/><br/>2.new操作符将新的对象传递给Engineer构造器，作为this关键字的值。<br/><br/>3.然后，构造器为对象创建一个叫做base的新属性，并且将base属性的值设置为WorkerBee的构造器。这使得WorkerBee构造器成为了Engineer对象的一个方法。<br/><br/>注意：base属性的名字并没有什么特别的。你可以使用任何的合法属性名；起名为base仅仅是为了直观一些。<br/><br/>4.下一步，构造器调用base方法，并将传递给构造器的参数中的两个(&#34;Doe, Jane&#34;和[&#34;navigator&#34;, &#34;javascript&#34;])以及字符串“engineering”再传递给base。在构造器内显式地使用“engineering”表明所有的 Engineer对象对于继承的dept属性都拥有相同的值，而且这个值会覆盖从Employee继承的值。<br/><br/>5.因为base是Engineer的方法，在对base的调用中，JavaScript将this关键字绑定到第一步创建的对象上。这样， WorkerBee函数依次将&#34;Doe, Jane&#34;and[&#34;navigator&#34;, &#34;javascript&#34;]参数传递给Employee构造函数。当Employee构造函数返回的时候，WorkerBee函数使用剩余的参数来设置 projects属性。<br/><br/>6.当从base方法返回的时候，Engineer构造器初始化对象的machine属性为“belau”。<br/><br/>7.当从构造器返回的时候，JavaScript将新对象赋值给jane变量。<br/><br/>你可能认为，已将在Engineer构造器的内部调用WorkerBee的构造器了，你就完成了对Engineer对象继承关系的设置。但是事实却不是这样。调用WorkerBee的构造器确保了Engineer对象开始的时候就具有了所有构造函数中指定的属性。然而，如果你之后又向Employee或者 WorkerBee的原型添加属性，那些属性将不会被Engineer对象所继承。举例来说，假设你写了如下的语句：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;Engineer (name, projs, mach) {<br/>&nbsp;&nbsp;this.base = WorkerBee;<br/>&nbsp;&nbsp;this.base(name, &#34;engineering&#34;, projs);<br/>&nbsp;&nbsp;this.projects&nbsp;&nbsp;= mach || &#34;&#34;;<br/>}<br/>jane = new Engineer(&#34;Doe, Jane&#34;,&nbsp;&nbsp;[&#34;navigator&#34;, &#34;javascript&#34;],&nbsp;&nbsp;&#34;belau&#34;);<br/>Employee.prototype.specialty = &#34;none&#34;;<br/></div></div><br/><br/>jane对象并不会继承specialty属性。你仍然需要显示地设置原型来确保动态的继承。假设你写了如下语句：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;Engineer (name, projs, mach) {<br/>&nbsp;&nbsp;this.base = WorkerBee;<br/>&nbsp;&nbsp;this.base(name, &#34;engineering&#34;, projs);<br/>&nbsp;&nbsp;this.projects&nbsp;&nbsp;= mach || &#34;&#34;;<br/>}<br/>Engineer.prototype = new&nbsp;&nbsp;WorkerBee;<br/><br/>jane = new Engineer(&#34;Doe, Jane&#34;,&nbsp;&nbsp;[&#34;navigator&#34;, &#34;javascript&#34;],&nbsp;&nbsp;&#34;belau&#34;);<br/>Employee.prototype.specialty = &#34;none&#34;;<br/></div></div><br/><br/>现在jane对象的specialty属性是&#34;none&#34;。<br/><br/><strong>又见属性继承</strong><br/><br/>上一部分描述了在JavaScript中，构造器和原型是如何提供层次和继承的。就像在所有的语言中一样，在之前的讨论中有一些细微之处还没有能够充分地暴露（not necessarily apparent）。而这一部分就来讨论这些细微之处中的几个。<br/><br/><strong>本地值和继承的值</strong><br/><br/>我们再来概括地看看属性的继承。正如在之前讨论的，当你访问一个对象的属性，JavaScript进行如下几步：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;* 查看是否存在本地值。如果存在，返回那个值。<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 如果不存在本地值，检查原型链（使用__proto__属性）。<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 如果在原型链中的某一个对象有该属性值，则返回那个值。<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 如果没有找到这个属性，说明这个对象没有这个属性值。<br/><br/>这一些列简单步骤的结果取决与你是如何在原型链上（along the way）定义对象的。在我们原来的例子中，我们有如下定义：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;Employee () {<br/>&nbsp;&nbsp;this.name = &#34;&#34;;<br/>&nbsp;&nbsp;this.dept =&nbsp;&nbsp;&#34;general&#34;;<br/>}<br/><br/>function&nbsp;&nbsp;WorkerBee () {<br/>&nbsp;&nbsp;this.projects = [];<br/>}<br/>WorkerBee.prototype&nbsp;&nbsp;= new Employee;<br/></div></div><br/><br/>根据如上定义，假设你创建一个WorkerBee的实例amy，语句如下：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>amy = new&nbsp;&nbsp;WorkerBee;<br/></div></div><br/><br/>amy对象有一个本地的属性，projects。name和dept属性的值并不是amy本地的，是从amy对象的__proto__属性取得的。所以，amy拥有如下属性：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>amy.name ==&nbsp;&nbsp;&#34;&#34;;<br/>amy.dept = &#34;general&#34;;<br/>amy.projects ==&nbsp;&nbsp;[];<br/></div></div><br/><br/>现在假设你改变了关联到Employee的原型的name属性的值：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>Employee.prototype.name&nbsp;&nbsp;= &#34;Unknown&#34;<br/></div></div><br/><br/>第一眼看来，你可能认为新的属性值会传递（propagate）到所有Employee的实例。然而，它却没有。<br/><br/>当你创建任何的Employee 对象的时候，那个实例就会为name属性取得一个本地的值（空字符串）。这意味着当你设置WorkerBee的原型为一个新建的Employee对象的时候，WorkerBee.prototype的name属性有一个本地的值。所以，当JavaScript查找amy对象（WorkerBee的一个实例）的name属性的时候，JavaScript在 WorkerBee.prototype中找到了name属性的值。所以它不会进一步顺着原型链访问Employee.prototype。<br/><br/>如果你想要在运行时改变改变对象的属性，并且让这个属性的新值被所有的该对象后代所继承，你就不能在对象的构造函数中定义这个属性。相反，你要将它添加在于构造函数向关联的原型上。例如，假设你将上面的代码修改如下：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;Employee () {<br/>&nbsp;&nbsp;this.dept =&nbsp;&nbsp;&#34;general&#34;;<br/>}<br/>Employee.prototype.name = &#34;&#34;;<br/><br/>function&nbsp;&nbsp;WorkerBee () {<br/>&nbsp;&nbsp;this.projects = [];<br/>}<br/>WorkerBee.prototype&nbsp;&nbsp;= new Employee;<br/>amy = new&nbsp;&nbsp;WorkerBee;<br/>Employee.prototype.name&nbsp;&nbsp;= &#34;Unknown&#34;;<br/></div></div><br/><br/>在这种情况下，amy对象的name属性就变成了&#34;Unknown&#34;。<br/><br/>就像这些例子展示的，如果你想要让对象的属性有默认值，而且又希望可以在运行时改变这个默认值，你就应该在构造器的原型中设置这个属性，而不是在构造函数中。<br/><br/><strong>确定实例关系</strong><br/><br/>你可能想要知道某个对象的原型链中究竟有些什么对象，所以你可以分辨出这个对象从哪些对象继承属性。在基于类的语言中，你可能拥有一个instanceof操作符来完成这项工作。JavaScript可没有提供instanceof，但是你可以自己写一个这样的函数。<br/><br/>正如在&#34;属性的继承&#34;中所讨论的，当你使用new操作符和构造函数创建新对象的时候，JavaScript将新对象的__proto__属性设置为构造函数的prototype属性的值。你可以使用这一点来测试原型链。<br/><br/>举个例子，假设你使用了我们上面使用的定义，原型都被合适地设置好了。像下面这样创建一个__proto__对象：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>chris = new&nbsp;&nbsp;Engineer(&#34;Pigman, Chris&#34;, [&#34;jsd&#34;], &#34;fiji&#34;);<br/></div></div><br/><br/>就这个对象而言，下面的语句都是成立（true）的。<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>chris.__proto__&nbsp;&nbsp;== Engineer.prototype;<br/>chris.__proto__.__proto__ ==&nbsp;&nbsp;WorkerBee.prototype;<br/>chris.__proto__.__proto__.__proto__ ==&nbsp;&nbsp;Employee.prototype;<br/>chris.__proto__.__proto__.__proto__.__proto__&nbsp;&nbsp;==&nbsp;&nbsp;Object.prototype;<br/>chris.__proto__.__proto__.__proto__.__proto__.__proto__&nbsp;&nbsp;== null;<br/></div></div><br/><br/>根据这一点，你可以像下面这样写一个instanceOf函数：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;instanceOf(object, constructor) {<br/>&nbsp;&nbsp;while (object&nbsp;&nbsp;!= null) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (object ==&nbsp;&nbsp;constructor.prototype) return&nbsp;&nbsp;true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;object =&nbsp;&nbsp;object.__proto__;<br/>&nbsp;&nbsp;}<br/>&nbsp;&nbsp;return&nbsp;&nbsp;false;<br/>}<br/></div></div><br/><br/>有以上定义，下面的表达式都成立(true)：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>instanceOf&nbsp;&nbsp;(chris, Engineer)<br/>instanceOf (chris, WorkerBee)<br/>instanceOf&nbsp;&nbsp;(chris, Employee)<br/>instanceOf (chris, Object)<br/></div></div><br/><br/>但是下面的表达式不成立：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>instanceOf&nbsp;&nbsp;(chris, SalesPerson)<br/></div></div><br/><br/><strong>构造器中的全局信息</strong><br/><br/>当你创建构造器的时候，如果你要在构造器中设置全局信息就需要小心了。举个例子，假设你想要给每个新的employee都自动设置一个独一无二的ID。你可能会这么定义Employee：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var idCounter =&nbsp;&nbsp;1;<br/><br/>function&nbsp;&nbsp;Employee (name, dept) {<br/>&nbsp;&nbsp;this.name = name ||&nbsp;&nbsp;&#34;&#34;;<br/>&nbsp;&nbsp;this.dept = dept ||&nbsp;&nbsp;&#34;general&#34;;<br/>&nbsp;&nbsp;this.id = idCounter++;<br/>}<br/></div></div><br/><br/>使用这个定义，当你创建一个新的Employee的时候，构造器会设置序列中的下一个ID并且将全局的IE计数器加一。所以，如果你的后续语句是：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>victoria = new&nbsp;&nbsp;Employee(&#34;Pigbert, Victoria&#34;, &#34;pubs&#34;)<br/>harry =&nbsp;&nbsp;new Employee(&#34;Tschopik, Harry&#34;, &#34;sales&#34;)<br/></div></div><br/><br/>victoria.id是1 并且harry.id是 2。第一眼看起来一切正常。然而，idCounter在每次Employee对象被创建的时候都会加一，而不管你是处于什么目的。如果你像我们之前那样创建整个Employee层次，每当我们设置一次原型的时候Employee构造器都会被调用一次。也就是说，假设你有如下代码：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var idCounter =&nbsp;&nbsp;1;<br/><br/>function&nbsp;&nbsp;Employee (name, dept) {<br/>&nbsp;&nbsp;this.name = name ||&nbsp;&nbsp;&#34;&#34;;<br/>&nbsp;&nbsp;this.dept = dept ||&nbsp;&nbsp;&#34;general&#34;;<br/>&nbsp;&nbsp;this.id = idCounter++;<br/>}<br/><br/>function&nbsp;&nbsp;Manager (name, dept, reports) {...}<br/>Manager.prototype = new&nbsp;&nbsp;Employee;<br/><br/>function&nbsp;&nbsp;WorkerBee (name, dept, projs) {...}<br/>WorkerBee.prototype = new&nbsp;&nbsp;Employee;<br/><br/>function&nbsp;&nbsp;Engineer (name, projs, mach) {...}<br/>Engineer.prototype = new&nbsp;&nbsp;WorkerBee;<br/><br/>function&nbsp;&nbsp;SalesPerson (name, projs, quota) {...}<br/>SalesPerson.prototype = new&nbsp;&nbsp;WorkerBee;<br/><br/>mac = new&nbsp;&nbsp;Engineer(&#34;Wood, Mac&#34;);<br/></div></div><br/><br/>进一步假设我们省略的定义中设置了base属性，并且调用了处于原型链上游的构造器。在这里例子中，到mac对象被创建的时候，mac.id 是 5。<br/><br/>根据应用的不同，计数器被额外多加这么几次不一定有没有影响。如果你关心计数器的精确值，一个可能的解决方案需要使用下面这个替代的构造器：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;Employee (name, dept) {<br/>&nbsp;&nbsp;this.name = name ||&nbsp;&nbsp;&#34;&#34;;<br/>&nbsp;&nbsp;this.dept = dept ||&nbsp;&nbsp;&#34;general&#34;;<br/>&nbsp;&nbsp;if (name) this.id&nbsp;&nbsp;= idCounter++;<br/>}<br/></div></div><br/><br/>当你Employee的实例是为了作为原型的时候，你不会向构造器提供参数。使用这个构造器定义，当你不提供参数的时候，构造器不会设置id值，也不会更新计数器的值。自然而然，想要让一个Employee取得id，你必须给employee指定一个姓名。在我们的例子中，mac.id将会是1。<br/><br/><strong>没有多继承（Multiple Inheritance）</strong><br/><br/>一些面向对象语言允许多继承。也就是，一个对象可以从不相关的多个父对象中继承属性和值。JavaScript并不支持多继承。<br/><br/>正如我们已经说的，属性值的继承发生在运行时，是通过JavaScript在对象的原型链中搜索一个属性值（实现的）。因为一个对象只有一个关联的原型，JavaScript不能动态地从多个原型链中继承属性。<br/><br/>在JavaScript中，你可以在一个构造函数中调用多个构造函数。这可以制造一种多继承的假象。举例来说，考虑如下的语句：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function&nbsp;&nbsp;Hobbyist (hobby) {<br/>&nbsp;&nbsp;this.hobby = hobby ||&nbsp;&nbsp;&#34;scuba&#34;;<br/>}<br/>function&nbsp;&nbsp;Engineer (name, projs, mach, hobby) {<br/>&nbsp;&nbsp;this.base1&nbsp;&nbsp;= WorkerBee;<br/>&nbsp;&nbsp;this.base1(name, &#34;engineering&#34;,&nbsp;&nbsp;projs);<br/>&nbsp;&nbsp;this.base2 =&nbsp;&nbsp;Hobbyist;<br/>&nbsp;&nbsp;this.base2(hobby);<br/>&nbsp;&nbsp;this.projects&nbsp;&nbsp;= mach || &#34;&#34;;<br/>}<br/>Engineer.prototype = new WorkerBee;<br/><br/>dennis = new&nbsp;&nbsp;Engineer(&#34;Doe, Dennis&#34;, [&#34;collabra&#34;], &#34;hugo&#34;)<br/></div></div><br/><br/>进一步假设WorkerBee的定义和我们之前看到的一样。在这种情况下，dennis对象有如下的属性：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>dennis.name ==&nbsp;&nbsp;&#34;Doe, Dennis&#34;<br/>dennis.dept ==&nbsp;&nbsp;&#34;engineering&#34;<br/>dennis.projects ==&nbsp;&nbsp;[&#34;collabra&#34;]<br/>dennis.machine == &#34;hugo&#34;<br/>dennis.hobby&nbsp;&nbsp;== &#34;scuba&#34;<br/></div></div><br/><br/>所以dennis确实从Hobbyist构造器中取得了hobby属性。然而，假设你之后又向Hobbyist构造器的原型中添加了属性：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>Hobbyist.prototype.equipment&nbsp;&nbsp;= [&#34;mask&#34;, &#34;fins&#34;, &#34;regulator&#34;, &#34;bcd&#34;]<br/></div></div><br/><br/>dennis对象并不会继承这个新的属性。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=308" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=308</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Javascript教程--用函数式编程技术编写优美的 JavaScript]]></title>
	  <author>
		 <name>yaohaixiao</name>
		 <uri>http://www.yaohaixiao.com/</uri>
		 <email>haixiao_yao@yahoo.com.cn</email>
	  </author>
	  <category term="" scheme="http://www.yaohaixiao.com/default.asp?cateID=4" label="Javascript" /> 
	  <updated>2008-11-05T16:20:09+08:00</updated>
	  <published>2008-11-05T16:20:09+08:00</published>
		  <summary type="html"><![CDATA[作者：<a href="http://www.yaohaixiao.com/mailto:shantanu@justawordaway.com">Shantanu Bhattacharya</a><br/>来源：<a target="_blank" href="http://www.ibm.com/developerworks/cn/web/wa-javascri&#112;t.html" rel="external">IBM developerWorks 中国</a><br/><br/><br/><div class="UBBPanel quotePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/quote.gif" style="margin:0px 2px -3px 0px" alt="引用内容"/> 引用内容</div><div class="UBBContent"><br/>函数式或声明性编程是非常强大的编程方法，正逐渐在软件行业流行起来。这篇文章将介绍一些相关的函数式编程概念，并提供有效使用这些概念的示例。作者将解释如何使用 JavaScript(TM)?（JavaScript 能导入函数式编程的构造和特性）编写优美的代码。<br/></div></div><br/><br/>函数式编程语言在学术领域已经存在相当长一段时间了，但是从历史上看，它们没有丰富的工具和库可供使用。随着 .NET 平台上的 Haskell 的出现，函数式编程变得更加流行。一些传统的编程语言，例如 C++ 和 JavaScript，引入了由函数式编程提供的一些构造和特性。在许多情况下，JavaScript 的重复代码导致了一些拙劣的编码。如果使用函数式编程，就可以避免这些问题。此外，可以利用函数式编程风格编写更加优美的回调。 <br/><br/><div class="UBBPanel quotePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/quote.gif" style="margin:0px 2px -3px 0px" alt="引用内容"/> 引用内容</div><div class="UBBContent"><br/><strong>函数式编程</strong><br/><br/>函数式编程只描述在程序输入上执行的操作，不必使用临时变量保存中间结果。重点是捕捉 “是什么以及为什么”，而不是 “如何做”。与将重点放在执行连续命令上的过程性编程相比，函数式编程的重点是函数的定义而不是状态机（state machine）的实现。 <br/><br/>大型知识管理系统应用程序从使用函数式编程风格上受益颇多，因为函数式编程简化了开发。<br/></div></div> <br/> <br/><br/>因为函数式编程采用了完全不同的组织程序的方式，所以那些习惯于采用命令式范例的程序员可能会发现函数式编程有点难学。在这篇文章中，您将了解一些关于如何采用函数式风格，用 JavaScript 编写良好的、优美的代码的示例。我将讨论： <br/><br/>函数式编程概念，包括匿名函数、调用函数的不同方法，以及将函数作为参数传递给其他函数的方式。<br/><br/>函数式概念的运用，采用的示例包括：扩展数组排序；动态 HTML 生成的优美代码；系列函数的应用。<br/><br/><strong>函数式编程概念</strong><br/><br/>在那些通过描述 “如何做” 指定解决问题的方法的语言中，许多开发人员都知道如何进行编码。例如，要编写一个计算阶乘的函数，我可以编写一个循环来描述程序，或者使用递归来查找所有数字的乘积。在这两种情况下，计算的过程都在程序中进行了详细说明。清单 1 显示了一个计算阶乘的可能使用的 C 代码。<br/><br/><strong>清单 1. 过程风格的阶乘</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>int factorial (int n)<br/>{<br/>&nbsp;&nbsp;if (n &lt;= 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;return 1;<br/>&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;return n * factorial (n-1);<br/>}<br/></div></div><br/><br/>这类语言也叫做过程性 编程语言，因为它们定义了解决问题的过程。函数式编程与这个原理有显著不同。在函数式编程中，需要描述问题 “是什么”。 函数式编程语言又叫做声明性 语言。同样的计算阶乘的程序可以写成所有到 n 的数字的乘积。计算阶乘的典型函数式程序看起来如 清单 2 中的示例所示。<br/><br/><strong>清单 2. 函数式风格的阶乘</strong><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>factorial n, wh&#101;re n &lt;= 0 &#160;&#160;&#160;&#160;:= 1<br/>factorial n&nbsp;&nbsp;&nbsp;&nbsp;:= foldr * 1 take n [1..]<br/></div></div> <br/><br/>第二个语句指明要得到从 1 开始的前 n 个数字的列表（take n [1..]），然后找出它们的乘积，1 为基元。这个定义与前面的示例不同，没有循环或递归。它就像阶乘函数的算术定义。一旦了解了库函数（take 和 foldr）和标记（list notation [ ]）的意义，编写代码就很容易，而且可读性也很好。<br/><br/><div class="UBBPanel quotePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/quote.gif" style="margin:0px 2px -3px 0px" alt="引用内容"/> 引用内容</div><div class="UBBContent"><br/>只用三行 Miranda 代码就可以编写例程，根据参数，使用广度优先或深度优先遍历处理 n 叉树的每个节点，而且元素可以是任何通用类型。&nbsp;&nbsp;<br/></div></div> <br/><br/>从历史上看，函数式编程语言不太流行有各种原因。但是最近，有些函数式编程语言正在进入计算机行业。其中一个例子就是 .NET 平台上的 Haskell。其他情况下，现有的一些语言借用了函数式编程语言中的一些概念。一些 C++ 实现中的迭代器和 continuation，以及 JavaScript 中提供的一些函数式构造（functional construct），就是这种借用的示例。但是，通过借用函数式构造，总的语言编程范例并没有发生变化。JavaScript 并没因为函数式构造的添加就变成了函数式编程语言。<br/><br/>我现在要讨论 JavaScript 中的函数式构造的各种美妙之处，以及在日常编码和工作中使用它们的方式。我们将从一些基本功能开始，然后用它们查看一些更有趣的应用。<br/><br/><strong>匿名函数</strong><br/><br/>在 JavaScript 中，可以编写匿名函数或没有名称的函数。为什么需要这样的函数？请继续往下读，但首先我们将学习如何编写这样一个函数。如果拥有以下 JavaScript 函数： <br/><br/><strong>清单 3. 典型的函数</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function sum(x,y,z) {<br/>&nbsp;&nbsp;return (x+y+z);<br/>}<br/></div></div> <br/><br/>然后对应的匿名函数看起来应当如下所示： <br/><br/><strong>清单 4. 匿名函数</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>function(x,y,z) {<br/>&nbsp;&nbsp;return (x+y+z);<br/>}<br/></div></div> <br/><br/>要使用它，则需要编写以下代码：<br/><br/><strong>清单 5. 应用匿名函数</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>var sum = function(x,y,z) {<br/>&nbsp;&nbsp;return (x+y+z);<br/>}(1,2,3);<br/>alert(sum);<br/></div></div> <br/><br/><strong>使用函数作为值</strong><br/><br/>也可以将函数作为值使用。还可以拥有一些所赋值是函数的变量。在最后一个示例中，还可以执行以下操作： <br/><br/><strong>清单 6. 使用函数赋值</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>var sum = function(x,y,z) {<br/>&nbsp;&nbsp;return (x+y+z);<br/>}<br/>alert(sum(1,2,3));<br/></div></div> <br/><br/>在上面 清单 6 的示例中，为变量 sum 赋的值是函数定义本身。这样，sum 就成了一个函数，可以在任何地方调用。<br/><br/><strong>调用函数的不同方法</strong><br/><br/>JavaScript 允许用两种方式调用函数，如清单 7 和 8 所示。 <br/><br/><strong>清单 7. 典型的函数应用</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>alert (“Hello, World!&#34;);<br/></div></div> <br/><br/>或<br/><br/><strong>清单 8. 用函数作为表达式</strong><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>(alert) (“Hello, World!&#34;);<br/></div></div> <br/><br/>所以也可以编写以下代码：<br/><br/><strong>清单 9. 定义函数之后就可以立即使用它</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>( function(x,y,z) { return (x+y+z) } ) (1, 2, 3);<br/></div></div> <br/><br/>可以在括号中编写函数表达式，然后传递给参数，对参数进行运算。虽然在 清单 8 的示例中，有直接包含在括号中的函数名称，但是按 清单 9 中所示方式使用它时，就不是这样了。<br/><br/><strong>将函数作为参数传递给其他函数</strong><br/><br/>也可以将函数作为参数传递给其他函数。虽然这不是什么新概念，但是在后续的示例中大量的使用了这个概念。可以传递函数参数，如 清单 10 所示。<br/><br/><br/><strong>清单 10. 将函数作为参数传递，并应用该函数</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };<br/><br/>var sum = function(x,y,z) {<br/>&nbsp;&nbsp;return x+y+z;<br/>};<br/><br/>alert( passFunAndApply(sum,3,4,5) ); // 12<br/></div></div> <br/><br/>执行最后一个 alert 语句输出了一个大小为 12 的值。<br/><br/><strong>使用函数式概念</strong><br/><br/>前一节介绍了一些使用函数式风格的编程概念。所给的示例并没有包含所有的概念，它们在重要性方面也没有先后顺序，只是一些与这个讨论有关的概念而已。下面对 JavaScript 中的函数式风格作一快速总结： <br/><br/>1. 函数并不总是需要名称。 <br/>2. 函数可以像其他值一样分配给变量。 <br/>3. 函数表达式可以编写并放在括号中，留待以后应用。 <br/>4. 函数可以作为参数传递给其他函数。 <br/><br/>这一节将介绍一些有效使用这些概念编写优美的 JavaScript 代码的示例。（使用 JavaScript 函数式风格，可以做许多超出这个讨论范围的事。）<br/><br/><strong>扩展数组排序</strong> <br/><br/>先来编写一个排序方法，可以根据数组元素的日期对数据进行排序。用 JavaScript 编写这个方法非常简单。数据对象的排序方法接受一个可选参数，这个可选参数就是比较函数。在这里，需要使用 清单 11 中的比较函数。<br/><br/><strong>清单 11. 比较函数</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function (x,y) {<br/>&#160;&#160;&#160;&#160;return x.date – y.date;<br/>}<br/></div></div> <br/> <br/>要得到需要的函数，请使用 清单 12 的示例。<br/><br/><strong>清单 12. 排序函数的扩展</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>arr.sort( function (x,y) {&#160;&#160;&#160;&#160;return x.date – y.date; } );<br/></div></div> <br/><br/>其中 arr 是类型数组对象。排序函数会根据 arr 数组中对象的日期对所有对象进行排序。比较函数和它的定义一起被传递给排序函数，以完成排序操作。使用这个函数： <br/><br/><strong>每个 JavaScript 对象都有一个 date 属性。</strong><br/> <br/>JavaScript 的数组类型的排序函数接受可选参数，可选参数是用来排序的比较函数。这与 C 库中的 qsort 函数类似。 <br/><br/><strong>动态生成 HTML 的优美代码</strong> <br/><br/>在这个示例中，将看到如何编写优美的代码，从数组动态地生成 HTML。可以根据从数据中得到的值生成表格。或者，也可以用数组的内容生成排序和未排序的列表。也可以生成垂直或水平的菜单项目。 <br/><br/>清单 13 中的代码风格通常被用来从数组生成动态 HTML。<br/><br/><br/><strong>清单 13. 生成动态 HTML 的普通代码</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var str=&#39; &#39;;<br/>for (var i=0;i&lt;arr.length;i++) {<br/>&nbsp;&nbsp;var element=arr[i];<br/>&nbsp;&nbsp;str+=... HTML generation code...<br/>}<br/>document.write(str);<br/></div></div> <br/><br/>可以用 清单 14 的代码替换这个代码。<br/><br/><strong>清单 14. 生成动态 HTML 的通用方式</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<br/>Array.prototype.fold=function(templateFn) {<br/>&nbsp;&nbsp;var len=this.length;<br/>&nbsp;&nbsp;var str=&#39; &#39;;<br/>&nbsp;&nbsp;for (var i=0 ; i&lt;len ; i++) <br/>&#160;&#160;&#160;&#160;str+=templateFn(this[i]);<br/>&nbsp;&nbsp;return str;<br/>}<br/><br/>function templateInstance(element) {<br/>&nbsp;&nbsp;return ... HTML generation code ...<br/>}<br/><br/>document.write(arr.fold(templateInstance));<br/></div></div> <br/><br/>我使用 Array 类型的 prototype 属性定义新函数 fold。现在可以在后面定义的任何数组中使用该函数。<br/><br/><strong>系列函数的应用</strong> <br/><br/>考虑以下这种情况：想用一组函数作为回调函数。为实现这一目的，将使用 window.setTimeout 函数，该函数有两个参数。第一个参数是在第二个参数表示的毫秒数之后被调用的函数。清单 15 显示了完成此操作的一种方法。 <br/><br/><strong>清单 15. 在回调中调用一组函数</strong><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>window.setTimeout(function(){alert(‘First!’);alert(‘Second!’);}, 5000);<br/></div></div><br/> <br/>清单 16 显示了完成此操作的更好的方式。<br/><br/><strong>清单 16. 调用系列函数的更好的方式</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.yaohaixiao.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>Function.prototype.sequence=function(g) {<br/>&nbsp;&nbsp;var f=this;<br/>&nbsp;&nbsp;return function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;f();g();<br/>&nbsp;&nbsp;}<br/>};<br/>function alertFrst() { alert(‘First!’); }<br/>function alertSec() { alert(‘Second!’); }<br/>setTimeout( alertFrst.sequence(alertSec), 5000);<br/></div></div> <br/><br/>在处理事件时，如果想在调用完一个回调之后再调用一个回调，也可以使用 清单 16 中的代码扩展。这可能是一个需要您自行完成的一个练习，现在您的兴趣被点燃了吧。<br/><br/><strong>结束语</strong><br/><br/>在许多领域中都可以应用 JavaScript 中的函数式编程，以优美的方式完成日常活动。这篇文章中的示例只介绍了几种情况。如果您找到了函数式编程的合适场景，并应用这些概念，那么您就会有更多的理解，并且可以增加您的优美程度。<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.yaohaixiao.com/article.asp?id=307" /> 
	  <id>http://www.yaohaixiao.com/default.asp?id=307</id>
  </entry>	
		
</feed>
