<?xml version="1.0" encoding="GBK" ?>
<rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dcterms="http://purl.org/dc/terms/">
 <channel>
  	  <title><![CDATA[互联网]]></title>
	  <link>http://blog.163.com/mike_gz</link>
	  <description><![CDATA[互联网研究 关注用户体验、产品策划、交互设计]]></description>
	  <language>zh-CN</language>
	  <pubDate>Fri, 23 Oct 2009 14:53:31 +0800</pubDate>
	  <lastBuildDate>Fri, 23 Oct 2009 14:53:31 +0800</lastBuildDate>
	  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
	  <generator><![CDATA[NetEase Space]]></generator>
	  <managingEditor><![CDATA[mike_gz]]></managingEditor>
	  <webMaster><![CDATA[罗西]]></webMaster>
		  <ttl>120</ttl>
	  <image>
	  	<title><![CDATA[互联网]]></title>
	  	<url>http://ava.bimg.126.net/photo/qBbUMA_e4_vynxfeCOWZzQ==/207447057836214073.jpg</url>
	  	<link>http://blog.163.com/mike_gz</link>
	  </image>
  <item>
  	<title><![CDATA[QQ开放——互联网最大一块多米诺骨牌]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/24753220099232395771</link>
    <description><![CDATA[<div><p align="left"><span>在你心目中，</span><span lang="EN-US">2009</span><span>年改变中国互联网行业格局的头件大事是什么？</span></p>
<p align="left"><span>马云宣布“为</span><span lang="EN-US">1000</span><span>万中小企业服务、让</span><span lang="EN-US">1</span><span>亿人就业、给</span><span lang="EN-US">10</span><span>亿人供应产品”的宏伟目标？</span></p>
<p align="left"><span>我认为不是。用互联网整合传统商业，是每一个网络大佬的梦想。</span><span lang="EN-US">4</span><span>年前，陈天桥发起过“整合所有互联网服务、给</span><span lang="EN-US">4</span><span>亿台电视机供应内容、影响</span><span lang="EN-US">10</span><span>亿中国人”的“盒子”计划。</span><span lang="EN-US">10</span><span>年内中国人和中国的企业都会上网，这是必然。那么为</span><span lang="EN-US">10</span><span>亿国人和几千万企业服务，当然是百度、腾讯这些垄断者的“默认目标”。</span></p>
<p align="left"><span>沸沸扬扬的网易从九城手里抢走《魔兽世界》？</span></p>
<p align="left"><span>当然也不是。虽然《魔兽》是最赚钱的网游，但一部游戏的代理权易手只
会埋葬一个落后的公司，却成就不了一个成功的公司。网易地位一直下滑，血拼九城情非得已。中国网游圈早已过了靠一款游戏的局部战斗就颠覆江湖座次的时代。
盛大和腾讯都是靠“平台”这种战略级创新才坐稳老大老二的位置。</span></p>
<p align="left"><span>门户老大新浪并购分众，成就仅次于央视的中国第二大媒体？</span></p>
<p align="left"><span>更不是。作为门户，去并购一个与互联网毫无关系的并非媒体的广告中介，是新浪在其领先优势被腾讯和搜狐追平之下的无奈之举。其<span>合并逻辑并非产品逻辑或用户逻辑</span>（新浪新闻的读者会因为写字楼的显示屏是新浪的而多看两眼吗？）。<span>而是赤裸裸的客户逻辑，</span>也就是新浪</span><span lang="EN-US">CEO</span><span>曹国伟所说的</span><span lang="EN-US">“</span><span>两家有重叠的广告客户</span><span lang="EN-US">”</span><span>，以及华尔街所喜欢的<span>资本逻辑</span>。</span></p>
<p align="left"><span>处于经济萧条里的中国互联网，似乎一直“保守”的走在既定轨道上。<strong>这一年，弱者制造噱头，但无伤大局。赢家维系地位，只是顺势而为。</strong>不过，却有一件会极大影响互联网格局、引发连锁反应、甚至改变创业环境的大事件正悄悄发生：</span></p>
<p align="left"><span>线索一，腾讯推出“</span><span lang="EN-US">QQ</span><span>返利平台”，向第三方</span><span lang="EN-US">B2C</span><span>网站导入用户。当用户登陆</span><span lang="EN-US">QQ</span><span>后，可通过</span><span lang="EN-US">QQ</span><span>返利频道的链接到达比如当当、京东、</span><span lang="EN-US">Vancl</span><span>等商城。购物后，将收到</span><span lang="EN-US">QQ</span><span>返回的占商品价格</span><span lang="EN-US">3%-22%</span><span>不等的现金。</span></p>
<p align="left"><span>线索二，</span><span lang="EN-US">QQ</span><span>空间接入第三方网站的功能。用户可以在其</span><span lang="EN-US">QQ</span><span>空间里直接玩耍到“</span><span lang="EN-US">5</span><span>分钟”所提供的比如种菜、偷菜这样的社交游戏，阅读到豆瓣网提供的有关热门书籍和电影的评论。</span></p>
<p align="left"><strong><span>一句话，腾讯开放了，开始与其它网站共享自己的</span></strong><strong><span lang="EN-US">4.5</span></strong><strong><span>亿活跃用户，这是中国互联网上数量最大、黏性最强的一个群体。</span></strong><span>可从两个方面来理解这一事件的影响力：第一，中国互联网霸主彻底的战略转变；由此导致第二，中国互联网的创业环境开始改善。</span></p>
<p align="left"><span lang="EN-US">2009</span><span>年第二季度，腾讯收入超过</span><span lang="EN-US">4.2</span><span>亿美金，相当于盛大、阿里巴巴、网易三家总和；运营利润超过</span><span lang="EN-US">2</span><span>亿美金，比这三家利润总和还要多。腾讯是中国互联网无可争议的霸主。而其地位的确立，来自于</span><span lang="EN-US">QQ</span><span>平台无比的黏性，以及与之配合的“封闭”战略。</span></p>
<p align="left"><span>在创新产品和模式层出不穷的互联网，腾讯并不急于创新，而是耐心观察。一旦有创新产品被证明有市场后，它快速模仿。然后利用</span><span lang="EN-US">QQ</span><span>平台的黏性，把用户从对手那里抢过来。它在休闲游戏上灭了联众，新闻流量超过新浪，正着手铲除迅雷、暴风、</span><span lang="EN-US">360</span><span>这些创业公司，在邮箱和输入法上正在取代网易和搜狐，网游收入刚刚超过盛大成为第一。</span></p>
<p align="left"><span>腾讯是所有人的对手，所以被称为“全民公敌”。很多有梦想的年轻人，会因为“在这个领域，如果腾讯出手一定会灭掉我”一条原因而放弃一个创新和一次创业。</span></p>
<p align="left"><span>而</span><span lang="EN-US">QQ</span><span>返利的推出，表明腾讯不会再推出与当当、京东类似的</span><span lang="EN-US">B2C</span><span>网站；</span><span lang="EN-US">5</span><span>分钟和豆瓣进驻</span><span lang="EN-US">QQ</span><span>空间，表明腾讯不会自己去研发一个种菜游戏，或者发展一个专注于书和电影的评论站点。相反，腾讯要用自己的力量去强壮这些合作伙伴。一旦能够共享</span><span lang="EN-US">QQ</span><span>的</span><span lang="EN-US">4.5</span><span>亿活跃用户，合作者的成长潜力立刻抬高了一个量级。只需要有好产品和硬口碑，它们不需要再投入巨大的资源去做宣传和圈用户。其生存环境，立刻有“柳暗花明又一村”的彻底转变。</span></p>
<p align="left"><span>那好，你当然会问：腾讯为什么会走这一步？而此举究竟意欲何为？</span></p>
<p align="left"><span>就在腾讯开放之前的</span><span lang="EN-US">7</span><span>月，我在广州跟网易前总编辑、多玩游戏网创始人李学凌有一次聊天。我说：“腾讯是否开放，是中国互联网最大的变数。”<strong>李学凌则说：“谁都不会自觉开放。关键是，谁能把腾讯打到不得不开放？”</strong>一语中的，这才是真问题。</span></p>
<p align="left"><span>即使风光如腾讯，却在两条业务线上一筹莫展：网络购物和搜索引擎。淘宝至今占到网购市场</span><span lang="EN-US">80%</span><span>的份额，腾讯的拍拍只有个位数。百度和</span><span lang="EN-US">Google</span><span>瓜分了近</span><span lang="EN-US">90%</span><span>的搜索引擎和竞价排名市场，腾讯的搜搜几乎无作为。这跟其在游戏、新闻、邮箱、无线增值业务上的后来居上形成极大反差。为什么？</span></p>
<p align="left"><span>很简单。“开放”而已。</span></p>
<p align="left"><span>淘宝的开放，是吸引第三方开发者和服务商，共同为淘宝网上的卖家和买
家服务。比如为他们开发各种应用，像网上试衣、网络砍价、网店模特、网店装修、网络分销。比如同物流、银行、支付、推广等合作伙伴帮卖家解决配送、贷款、
收款、营销等问题。比如和大量网站相互嵌套，让网民在其它网站上也可以浏览来自淘宝的网店。</span></p>
<p align="left"><span>如此形成一个生态体系。要跟淘宝作战，就是跟上千万卖家、几十万第三方开发者和服务商、几十家物流公司和银行、几十家合作网站同时竞争。腾讯做邮箱只需要打败一个网易、做游戏只需要打败一个盛大，其难度，跟挑战大淘宝的“蚂蚁雄兵”绝不在一个量级。</span></p>
<p align="left"><span>百度的开放，是成为中国</span><span lang="EN-US">30</span><span>万中小网站的“流量变现平台”。这些网站把流量导入百度，并根据对百度广告的点击效果获得收入。百度在</span><span lang="EN-US">2008</span><span>年分给这个“百度联盟”的收入就超过</span><span lang="EN-US">4</span><span>亿。而在这个联盟与广告主之间，还有一个庞大的“搜索引擎优化（</span><span lang="EN-US">SEM</span><span>）”市场，即帮助大量中小网站优化其网站结构和内容，以能在百度这个搜索平台上抢到更多流量和收入；帮助几十万中小企业在百度这个营销平台上更有效率的投放广告。</span><span lang="EN-US">2008</span><span>年</span><span lang="EN-US">SEM</span><span>市场至少有</span><span lang="EN-US">10</span><span>亿，养活了上万小公司。</span></p>
<p align="left"><span>如此也形成一个生态体系。要想颠覆百度，就得同时让这几十万中小网站和几万</span><span lang="EN-US">SEM</span><span>商同时倒戈。这跟之前腾讯擅长的“单一界面的产品”有本质区别。</span></p>
<p align="left"><span>诸如下载软件迅雷、播放软件暴风、输入法搜狗等都属于</span><span lang="EN-US">“</span><span>单一界面产品</span><span lang="EN-US">”</span><span>。其特征是：只存在用户和产品之间的信息交换，不需要第三方资源介入和信息共享，即</span><span lang="EN-US">“</span><span>封闭性</span><span lang="EN-US">”</span><span>。“单一界面产品”的起步都依赖技术壁垒或先发优势，比如下载软件、播放软件、邮箱或输入法，都是一家公司独立运营，缺乏与其它商业体间的合作、共生。</span></p>
<p align="left"><span>牢牢黏住用户的腾讯能轻易剿灭一个精妙的单一界面产品，却难以复制一个已经成型的生态链。这就跟其它网站没办法从已成型为一个用户集群的</span><span lang="EN-US">QQ</span><span>平台抢走用户一样。说白了，腾讯之所以成为今天的网络霸主，跟它之所以不能撼动百度和淘宝，其原因形式不同，但本质相同。</span></p>
<p align="left"><strong><span>于是，腾讯终于做出判断：只有成就所有人，而不是歼灭所有人，才能成就长久霸业。</span></strong><span>中国互联网最大一块多米诺骨牌就此倒下。那么，这之后的中国互联网如何变化？</span></p>
<p align="left"><span>前面说，腾讯是否开放，是中国互联网最大的变数。变数就在于：腾讯不
开放，很多网站都可以选择不开放；而一旦腾讯开放，那些与腾讯有竞争的网站则必须开放。逻辑很明白：腾讯已经有一个牢不可撼的用户群，而如果再以这个用户
群为核心团结一票提供各种服务的中小网站，形成一个互助共生的生态体系，那么，除非国家政策或法律问题，在商业层面，目前几乎看不到任何颠覆腾讯的可能
性。</span></p>
<p align="left"><span>在全球，当社交网络领袖</span><span lang="EN-US">Facebook</span><span>选择开放，逼迫搜索引擎领袖</span><span lang="EN-US">Google</span><span>跟进，那么开放就成为整个行业不得不遵守的规则。这跟腾讯在中国市场的影响力是一个道理。最有资格和动力实行保守和封闭路线的就是垄断者，而一旦垄断者开放，它的垄断地位就将根深蒂固。其他人不能阻挡，只能顺从。</span></p>
<p align="left"><span>接下来，会有五个必然发生的事情：</span></p>
<p align="left"><span>第一，</span><span lang="EN-US">QQ</span><span>空间最直接的对手，社交网络市场里的校内、</span><span lang="EN-US">51</span><span>以及一直封闭的开心网，都必须全面开放。这只是个时间问题。</span></p>
<p align="left">
</p><p>第二，门户必须开放，向外部输出用户。就在8月初腾讯推出“QQ返利频道”之后，网易立即跟进，推出“网易返现频道”。</p>
<p>第三，大量与开放平台对接的中小网站将快速取得大量用户和收入。尤其在一些细节功能和缝隙市场这些腾讯不会进入的领域，创业环境将大为改善，比如与豆瓣类似的依靠出产精品内容取胜的垂直社区，比如与5分钟类似的各种小型社交游戏的开发商。</p>
<p>第四，那些已经与腾讯为敌的网站生存环境将恶化。通过开放获取更多功能和服务以及合作伙伴，QQ平台的黏性将进一步增强。靠单一产品、单一社区就想独善其身的可能会越来越小。</p>
<p>所以有第五，将来的中国互联网，大势力和大网站崛起的空间越来越小，相反长尾市场和中小网站更为兴盛。因为腾讯这样的已经崛起的平台一定会守住有战
略地位的、尤其是一个单一产品就可以覆盖所有用户群的领域：比如门户、游戏、邮箱、搜索、下载、输入法。只有市场容量相对小、需要细分市场才能满足用户多
种需求的领域才会拱手于人。</p>
<p>同时，腾讯们的收入将会再上一个量级，并且更加多元。诸如豆瓣和5分钟这样的合作伙伴每赚一分钱，都会分账给腾讯。我估计，腾讯年收入会从目前16
亿美金增长到3年后的40亿。市值会从目前300亿美金，增长到3年后的1000亿，成为仅次于Google的全球第二大互联网公司。</p>
<p>从关注创新这个角度讲，互联网江山已定、难有新平台崛起，这是个坏消息。而相应的好消息是，在缝隙市场、长尾领域为这些平台服务的小机会就更容易依附于平台开花结果。不久前盛大CEO陈天桥如此总结互联网的未来：平台集中化，内容分散化。也是一语中的。</p></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/24753220099232395771</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/24753220099232395771</guid>
    <pubDate>Fri, 23 Oct 2009 14:39:57 +0800</pubDate>
    <dcterms:modified>2009-10-23T14:39:57+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[雅虎衰落源于公司领袖缺乏远见与决断个性]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200992192258634</link>
    <description><![CDATA[<div>雅虎的衰落，公司领袖负有不可推卸的责任，杨致远缺乏做出决断的个性和能力。
<p>　　与充满商业智慧的微软和Google相比，雅虎显得太过幼稚。</p>
<p>
　　我之前创立的3721卖给了雅虎，后来还有过一段合作，所以对它有较深入的了解。我曾多次对雅虎发表过看法，很多人认为我是出于所谓”个人恩怨”，实际上没有必要，我只是惋惜这家公司失去了太多机会。</p>
<p>
　　雅虎的衰落，公司领袖负有不可推卸的责任。无论精神领袖杨致远还是前CEO塞梅尔，他们都是不错的人，但并非天才，缺乏真正领袖需要的气质。在面对
Google、微软的竞争时，他们手足无措，没有方向感。最初Google的创始人曾找到雅虎要出售技术，但遭到拒绝，在Google遭遇危机时雅虎又错
过了收购机会。从这一点上，就能看出来，雅虎是一家缺乏远见的公司。后来跟Google争夺Youtube时，雅虎因为犹豫不决而败下阵
来;Facebook又被微软以2.4亿美元的价格(只占1.6%股权)将估值抬高，不可能收购。</p>
<p>
　　失去机会还不可怕，更要命的是，雅虎2000年时跟新创立的Google达成合作，在网站上使用其搜索技术，给后者带来了流量、品牌和收入。雅虎事实上是自己培养了自己的掘墓人。</p>
<p>
　　雅虎在2004年醒悟过来，中止了与Google的合作，推出了自己的搜索技术，之前收购了Inktomi，在中国也收购了3721。我当时参与了雅
虎搜索战略的规划，但感觉整个公司已经形成了压制创新的文化，任何人提出任何新想法，都会有很多人站出来挑毛病，而不是进行建设性的讨论。</p>
<p>
　　在中国市场，当时我先斩后奏，推出了独立的搜索服务品牌”一搜”，没有花多少钱就做了起来，但雅虎总部还是充满了质疑。我认为一年只要投入几百万美
元，就完全可以赶超还不强大的百度，那时Google还没正式进入中国。但总部的管理者只片面看待投资回报率，不愿意为公司的未来进行投入。就像种地一
样，只知收获，而不去施肥和耕耘，最终就会盐碱化、沙漠化，失去生命力。</p>
<p>
　　到了后来遭受各界质疑时，雅虎就把塞梅尔当替罪羊赶走了。但我认为核心问题在于精神领袖杨致远，他的性格很温和，不是能带兵打仗的人，不能果断做出决
策。在公司面临困境时，领导力非常重要，领袖要看到方向，带给员工信心，并敢于在信息不明朗的情况下做决策。在战场上，即便做一个坏的决策，也比不做决策
好，否则会贻误战机。杨致远在2007年中接任CEO后，一直没有拿出明确的战略，也没有在搜索领域集中兵力。尽管雅虎换了CEO，但施政纲领和组织架
构、企业文化都没有改变。</p>
<p>
　　在2008年与微软的收购案中，杨致远缺乏决断的个性再次成为雅虎寻求突破的阻碍。微软提出收购后，杨致远没有清晰的表态”战”还是”降”，暧昧的态
度向团队传递了错误的信息。这种首鼠两端、患得患失的做法，让他失去了团队的信任，很多人都流失了，去了微软或Google。在此过程中，Google玩
了一招漂亮的阳谋，也伸出了橄榄枝，让杨致远更加摇摆不定，阻止了微软的收购，最后还以”无法通过反垄断审查”为名始乱终弃。在微软和
Google都表现出较高的商业智慧的同时，雅虎就显得太幼稚了，衰落就不可避免。</p>
<p>　　PS：雅虎现任CEO卡罗尔·巴茨的个性够鲜明，也敢想敢说敢做，不知她能否给雅虎带来美好的明天。<br><br>转自：http://blog.sina.com.cn/s/blog_49f9228d0100fn08.html<br></p></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200992192258634</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200992192258634</guid>
    <pubDate>Wed, 21 Oct 2009 09:22:58 +0800</pubDate>
    <dcterms:modified>2009-10-21T09:22:58+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[下一站，信仰]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200992192156176</link>
    <description><![CDATA[<div><p>CTO李一男来了，产品总监<a title="老边走了" target="_blank" href="http://www.donews.com/Content/200903/1ca25f5de4d44000869a02c4e117c875.shtm">老边走了</a>，产品副总裁<a title="俞军" target="_blank" href="http://uicom.net/blog/?p=836">俞军走了</a>，百度的产品发言权从技术到产品(刘建国到俞军)，又轮回到了技术（俞军到李一男）。百度产品三巨头，目前仅剩首席产品设计师<a title="云丰" target="_blank" href="http://hi.baidu.com/whomi">孙云丰</a>。</p>
<p>论对于中国网民搜索行为和搜索习惯的了解，这个星球上估计没有第二个人比云丰强。他每天打交道最多的词应该是“Query
”。网民在怎么搜索，需要什么样的搜索产品似乎没有人比他了解的清楚，每个Query背后藏着怎么样的用户需求和行为习惯，他可谓是了如指掌。这从他前不
久在百度世界上的<a title="一个小分享" target="_blank" href="http://tech.sina.com.cn/i/2009-08-18/15533362379.shtml">一个小分享</a>，即可见一斑。</p>
<p>在产品上孙云丰有着独到的见解和判断能力，而且是一个极其强势的人，处理方式也很直接，直接到会让别人偶尔失去“自尊”。比如，他会毫不忌讳的告诉你“这个设计就是狗屎，应该重做”。他是产品评审委会里最接近网民的人，拥有对产品的否决权。</p>
<p>同时，孙云丰是一个追求专业到偏执的人，据说他玩相机的时候“前3000张照片绝不贴出来”。所以，这样的人往往也是对办公室政治最没有兴趣的人，一门心思就只在业务、在搜索，我只想做好我的专业！其实，他做的不是搜索，是信仰。</p>
<p>百度的产品文化其实就是一种信仰，对于搜索和互联网的信仰。这种信仰表现在每个PM都是超级网虫，表现在每个人都写博客、泡社区，表现在连午餐桌上都要谈论互联网，而不像其他公司那样除了买房就是股票。更不会成天想着如何<a title="拿技术创新去作套现" target="_blank" href="http://tech.sina.com.cn/i/2009-07-23/09413287309.shtml">拿技术创新去作套现</a>。</p>
<p>有信仰的人是最好满足的，也是最难满足的，钱往往解决不了他们的问题。</p>
<p>有人说，老边和俞军的走是因为股票可以完整套现了，所以选择离开，去上海过渡一下，未来说不定要再走到一起做事情。其实，如果当前环境还能给他们信
仰，给他 们空间，那又何必走呢？ 所以，我更认为他们的走，是因为“信仰”，因为信仰的缺失，所以离开。因为，在下一站也许可以继续找到信仰。</p>
<p>俞军和老边走了，大部分还有信仰的PM跟李明远到了有啊，焦可也基本上不做产品了，东宝<a title="跟随边江而去" target="_blank" href="http://hi.baidu.com/dongbao/blog/item/2c0fd9f913ad7853252df2f6.html">跟随老边而去</a>了，“<a title="百度产品学院" target="_blank" href="http://hi.baidu.com/dongbao/album/item/05f0f7361777b4170a55a9b8.html">百度产品学院</a>”的核心所剩无几… 。云丰还能保持自己的信仰吗？还能找到信仰吗？</p>
<p>如果云丰真的也走了。明远、焦可、李明、田小萌，你们还能呆多久？你们的信仰还在吗。<br><br>转自：http://uicom.net/blog/?p=844<br></p></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200992192156176</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200992192156176</guid>
    <pubDate>Wed, 21 Oct 2009 09:21:56 +0800</pubDate>
    <dcterms:modified>2009-10-21T09:21:56+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[windowsXP不必要的服务]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/2475322009919464736</link>
    <description><![CDATA[<div>在xp系统中，有近90个服务，默认开启了30多个服务，而事实上我们只需要其中几个就够用了。禁止所有不必要的服务可以为您节省n多的内存和大量系统资源 不过，由于默认安装完Windows XP后，系统会开启很多服务，其中不少对于普通用户根本用不到或暂时用不到，反而浪费了相当多的内存和系统资源，特别是内存，影响了系统启动和运行的速度。但是迫于水平实在有限 不敢乱关 一些服务 所以找了好多地方 找了一写相关文章过来 希望能给那些和我一样痛苦着用xp的朋友一些帮助部分做了相关修改： <BR><BR>关闭下边的无用服务后,在资源管理器里,你会看到PF使用值会降低30M以上<BR><BR>在 “开始” 的 “运行” 中 输入： <BR>services.msc <BR>进入XP自带服务修改列表 <BR><BR>可以选择关闭，手动，还是自动． <BR><BR>自动为跟windows一起启动。 <BR><BR>手动为需要时它自行启动。 <BR><BR>关闭为永远不启动。 <BR><BR>开始吧： <BR><BR>alerter -错误警报器，^^，关闭。<BR><BR><BR>application layer gateway service -给与第三者网络共享/防火墙支持的服务，有些防火墙/网络共享软件需要。占用1。5mb内存。 <BR><BR><BR>application management-用于设定，发布和删除软件服务。<BR><BR><BR>automatic updates -windows自动更新，靠，滚！ <BR><BR><BR>background intelligent transfer service -这个服务原是用来实现http1.1服务器之间的信息传输，微软称支持windows更新时断点续传 <BR><BR><BR>clipbook - 用与局域网电脑来共享 粘贴/剪贴的内容。（靠，想得出！）<BR><BR><BR>com+Event system -一些 COM+ 软件需要，检查你的 c:\program files\ComPlus Applications 目录，没东西可以把这个服务关闭． <BR><BR><BR>COM+Event system application －同上 <BR><BR><BR>COmputer browser － 用来浏览局域网电脑的服务，但关了也不影响浏览！^^ <BR><BR><BR>cryptographic services -windows更新时用来确认windows 文件指纹的，我更新时才开启一下。<BR><BR><BR>DHCP client－静态IP者需要（xDSL 等）小猫就不用了！！ <BR><BR><BR>Distributed link tracking client－用于局域网更新连接信息，比如在电脑A有个文件，在B做了个连接，如果文件移动了，这个服务将会更新信息。占用4兆内存。<BR><BR><BR>Distributed Transaction coordinator－无聊的东西。 <BR><BR><BR>DNS Client－DNS解析服务。。无聊～～ <BR><BR><BR>Error reporting service -错误报告器，把windows中错误报告给微软，无聊～～～～～ <BR><BR><BR>＊Event Log- 系统日志纪录服务，很有用于查找系统毛病． <BR><BR><BR>Fast user switching compatibility－多用户快速切换服务．．无聊 <BR><BR><BR>help and support -帮助，无聊，还是无聊帮助．．哈哈 <BR><BR><BR>Human interface device access－支持”弱智“电脑配件的。。比如键盘上调音量的按钮等等。。 <BR><BR><BR>IMAPI CD-burning COM service －xp刻牒服务，用软件就不用了占用1。6兆内存 <BR><BR><BR>Indexing service -恐怖的xp减速的东东！！！关关关！！！ <BR><BR><BR>Internet Connection Firewall(ICF).........-xp防火墙。。不用就关。 <BR><BR><BR>IPSEC Services－大众用户连边都沾不上。 <BR><BR><BR>Logical Disk manager －磁盘管理服务。。需要时它会通知你，所以一般关。 <BR><BR><BR>Logical Disk manager administrative service－同上。 <BR><BR><BR>messenger -不是msn，不想被骚扰的话就关。注：妖刺就是利用这个。 <BR><BR><BR>MS software shadow copy provider－无用，据说是备份用的。。我看什么用都没。<BR><BR><BR>Net Logon－登陆 Domain Controller 用的，大众用户快关！ <BR><BR><BR>Netmeeting remote desktop sharing－用netmeeting 实现电脑共享。。晕！关！！ <BR>Network Connections - 上网／局域网要用的东东！ <BR><BR><BR>Network DDE －和clipbook一起用的，无聊～～～～ <BR><BR><BR>Network DDE DSDM －同上 <BR><BR><BR>Network Location Awareness－如有网络共享或ICS/ICF可能需要.(服务器端） <BR><BR><BR>NT LM Security support provider－telnet 服务用的东东，关！！ <BR><BR><BR>NVIDIA Driver Helper service -nvidia 显卡帮助，关！ <BR><BR><BR>PDEngine - perfectdisk 引擎 <BR><BR><BR>PDScheduler -perfectdisk 计划服务 <BR><BR><BR>PerFORMance logs and alerts－记录机器运行状况而且定时写入日志或发警告，内容可能过于专业，所以。。自己决定。 <BR><BR><BR>＊Plug and Play- 自动查测新装硬件，即插即用，开着吧～～～ <BR><BR><BR>Portable media serial number－绝对无用，无聊之及。<BR><BR><BR>Print Spooler -打印机用的，我打印时才开一下。<BR><BR><BR>Protected Storage－储存本地密码和网上服务密码的服务，包括填表时的“自动完成”功能。 <BR>QoS RSVP -关！就是那个20％的 QoS <BR><BR><BR>Remote access auto connection manager－宽带者／网络共享可能需要！！ <BR><BR><BR>Remote desktop help session manager－远程帮助服务，傻透，占用4兆内存。 <BR><BR><BR>＊Remote Procedure Call (RPC) -系统核心服务！ <BR><BR><BR>Remote Procedure Call LOCATOR－这个倒没什么用，管理 RPC 数据库服务，占用1兆内存。 <BR><BR><BR>remote registry －远程注册表运行／修改。大漏洞，还不快关！！ <BR><BR><BR>removable storage －一般情况下不用，磁带备份用的。 <BR><BR><BR>routing and remote access－哈哈。。不知者关！ <BR><BR><BR>secondary logon－给与administrator 以外的用户分配指定操作权．晕～～～<BR><BR><BR>security accounts manager－像 Protected Storage, IIS Admin 才需要。 <BR><BR><BR>server -局域网文件／打印共享需要的。 <BR><BR><BR>shell hardware detection－给有些配置自动启动，像内存棒，和有些cd驱动等 <BR><BR><BR>smart card -关！1。4兆内存 <BR><BR><BR>smart card helper -关！ <BR><BR><BR>SSDP Discovery service－没有什么硬件利用这个服务。。 <BR><BR><BR>system event notification－记录用户登录／注销／重起／关机信息。。谁管这些。。 <BR><BR><BR>system restore service -系统还原服务，吃资源和内存的怪兽。。虽然有时用到，自己决定。<BR><BR><BR>task scheduler－windows 计划服务啦，^^．<BR><BR><BR>TCP/IP NetBIOS helper－如果你的网络不用 Netbios 或WINS，关了． <BR><BR><BR>Telephony - 拨号服务，如果你的宽带不用拨号，那么关了它。<BR><BR><BR>telnet -大漏洞，我第一个关的就是这个．这根dos中 telnet 命令没关系。2兆内存。<BR><BR><BR>terminal services－实现远程登录本地电脑，快速用户切换和远程桌面功能需要，不用这些功能就关了吧。 <BR><BR><BR>themes -给xp打扮漂亮的东东，不要太花锹的就关了。 <BR><BR><BR>uninterruptible power supply－停电保护设备用的。。。没有的就关。 <BR><BR><BR>universal plug and play device host－同SSDP Discovery Service ，没用． <BR><BR><BR>upload manager－用来实现服务器和客户端输送文件的服务，简单文件传输不需要这个！<BR><BR><BR>volume shadow copy－同MS Software Shadow Copy Provider，无用． <BR><BR><BR>webclient－可能和以后的．net技术有联系，安全起见，我关得实实的！ <BR><BR><BR>＊Windows Audio - 控制着你听到的声音。关了就没声音了！！ <BR><BR><BR>Windows Installer -windows的MSI安装服务，建议设成手动。 <BR><BR><BR>windows image acquisition (WIA) -有些数码相机和扫描器用的，我的扫描器觉得它没用。<BR><BR><BR>＊Windows Management Instrumentation - 满重要的服务，是管”服务依靠”的，但关了会出现奇怪的问题． <BR><BR><BR>windows management instrumentat </div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/2475322009919464736</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/2475322009919464736</guid>
    <pubDate>Mon, 19 Oct 2009 16:06:04 +0800</pubDate>
    <dcterms:modified>2009-10-19T16:06:04+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[对设计和技术的误解]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200988104555872</link>
    <description><![CDATA[<div><P style="TEXT-INDENT: 2em">在互联网产品相关职能中，有部分叫做前端开发(front-end development)的工作，到底属于设计还是技术？我个人认为是既要设计水准也要技术含量，不过讲起来似乎有点矛盾。曾经争论不休，因为之前的软件项目管理从没有涉及，这也就是曾经说过，除可用性外只互联网产品才有的可访问性、兼容性、标准化等指标。</P>
<P style="TEXT-INDENT: 2em">! ]. J&nbsp;&nbsp;n, `. P0 r" n' d' Z, J通过前端开发的例子更能证明，考虑web-based的可用性和可访问性必然至少了解客户端编码（不是第一次第二次提了），这是我们职业生涯进阶的门槛。因为构成互联网产品基础的就是每个客户端页面，否则所有idea只建立在空中花园之上。尤其项目管理中，90%的矛盾来源于沟通不善，90%的沟通不善来源于知识结构不对等。/ {# p: C% t+ d3 w* s" D</P>
<P style="TEXT-INDENT: 2em">在网站产品管理发展相对成熟的过程中，几乎所有公司都是把前端开发安排在产品团队的组织体系之下。从这点起我开始深入思考设计与技术的联系，“做技术的、做设计的”常见于资深工程师和资深设计师自谦的介绍，但是我越来越发现这个说法有问题。通常理解做技术就是写代码，做设计就是画图什么的，其实都不太准确。) \) a1 J0 e% z; v</P>
<P style="TEXT-INDENT: 2em">资深工程师都了解，整个代码框架、逻辑需要精心设计才可能达到良好实用性、适应性、可维护性、可扩展性、可靠性、可量测性的境界。好代码就是艺术品，那不是设计是什么？岂止技术那么简单？软件技术领域有个热门职位叫Software Architect，也有专职Test Architect等。0 P: P) z3 K8 Q) \* E</P>
<P style="TEXT-INDENT: 2em">资深设计师都了解，熟知整个业务体系，充分建立起以用户为中心的设计模式和产品管理机制，保证产品用户友好、开发者友好、搜索引擎友好并不是容易的事情，那不是技术是什么？又岂止设计那么简单？互联网技术领域也有类似职位叫Information Architect，在欧美相对成熟。</P>
<P style="TEXT-INDENT: 2em">, A/ x6 j/ E+ t9 t% O( X- m% z" k&amp; p也就是说，真正工程师、设计师解决的问题，都需要architecting，都需要designing，都有技术含量。并且在信息传达角度，通常所说“设计”与“技术”并不在同个维度。反过来理解，没有创造性的工程师只是程序员，没有创造性的设计师也就是设计（专）员吧。</P></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200988104555872</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200988104555872</guid>
    <pubDate>Tue, 8 Sep 2009 10:45:55 +0800</pubDate>
    <dcterms:modified>2009-09-08T10:45:55+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[JavaScript优化细节]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200951191747234</link>
    <description><![CDATA[<div>转<br><br><p>作为一名网站开发WEB前端工程师，对自己开发的网站项目应该尽可能地对其性能进行优化，现在互联网上搜索到的网站性能优化多是翻译转载自
Yahoo14条或34条。Yahoo的优化建议关注在大的方面，下面，W3C
Group为大家呈现WEB前端开发高性能优化部分之JavaScript的优化细节！</p>
<p><strong>一、避免出现脚本失控</strong></p>
<p>不论什么脚本，在任何时间、任何浏览器上执行，都不应该超过100毫秒。如果实际执行的时间长于这个底限，一定要将进程分解成若干更小的代码段。</p>
<p>脚本失控基本上有以下四个方面的原因：</p>
<p><strong>1. 在循环中执行了太多的操作</strong></p>
<p>解决这个问题的诀窍就是用下面这两个问题来评估每个循环：</p>
<ol><li>这个循环必须要同步执行么？</li><li>循环里面的数据，必须要按顺序执行么？</li></ol>
<p>如果1和2都可以否定，那么建议使用setTimeout方式将循环体切分成小块进行异步处理</p>
<p>将循环中的定义变量及初始化操作放到循环外。参见：<a href="http://www.w3cgroup.com/article.asp?id=111" target="_blank">http://www.w3cgroup.com/article.asp?id=111</a></p>
<p><strong>2. 臃肿的函数体</strong></p>
<p>在JavaScript中，我们应该尽可能的用局部变量来代替全局变量!</p>
<p>理解JavaScript作用域链。参见：<a href="http://www.jslab.org.cn/?tag=ScopeChainAndClosure">http://www.jslab.org.cn/?tag=ScopeChainAndClosure</a></p>
<p>理解原型链。参见：<a href="http://www.jslab.org.cn/?tag=prototypeChain">http://www.jslab.org.cn/?tag=prototypeChain</a></p>
<p><strong>3. 过多的递归</strong></p>
<p>使用迭代方式替代递归，采用memoization技术优化递归</p>
<p>斐波那契数列的递归算法优化，参见：<a href="http://www.jslab.org.cn/?tag=Memoization" target="_blank">http://www.jslab.org.cn/?tag=Memoization</a></p><p><br></p><p><strong>4. 过多的DOM调用</strong></p>
<p>在Web开发中，JavaScript的一个很重要的作用就是对DOM进行操作。可你知道么？对DOM的操作是非常昂贵的，因为这会导致浏览器执行回流（reflow）操作。而执行了过多的回流操作，你就会发现自己的网站变得越来越慢了。我们应该尽可能的减少DOM操作。</p>
<p>回流操作主要会发生在几种情况下：</p>
<ul><li>改变窗体大小</li><li>更改字体</li><li>添加移除stylesheet块</li><li>内容改变哪怕是输入框输入文字</li><li>CSS虚类被触发如 :hover</li><li>更改元素的className</li><li>当对DOM节点执行新增或者删除操作或内容更改时。</li><li>动态设置一个style样式时（比如element.style.width="10px"）。</li><li>当获取一个必须经过计算的尺寸值时，比如访问offsetWidth、clientHeight或者其他需要经过计算的CSS值（在兼容DOM的浏览器中，可以通过getComputedStyle函数获取；在IE中，可以通过currentStyle属性获取）。</li></ul>
<p>解决问题的关键，就是限制通过DOM操作所引发回流的次数:</p>
<p>1.在对当前DOM进行操作之前，尽可能多的做一些准备工作，保证N次创建，1次写入。</p>
<p>2.在对DOM操作之前，把要操作的元素，先从当前DOM结构中删除：</p>
<ol><li>通过removeChild()或者replaceChild()实现真正意义上的删除。</li><li>设置该元素的display样式为“none”。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 修改操作完成后，将上面这个过程反转过来，建议使用第2种方式。</li></ol>
<p>3.CSS部分</p>
<p>另外一个经常引起回流操作的情况是通过style属性对元素的外观进行修改，如element.style.backgroundColor = "blue";</p>
<p>每次修改元素的style属性，都肯定会触发回流操作，要解决这个问题可以：</p>
<ol><li>使用更改className的方式替换style.xxx=xxx的方式。</li><li>使用style.cssText = '';一次写入样式。</li><li>避免设置过多的行内样式</li><li>添加的结构外元素尽量设置它们的位置为fixed或absolute</li><li>避免使用表格来布局</li><li>避免在CSS中使用JavaScript expressions(IE only)</li></ol>
<p>4.将获取的DOM数据缓存起来。这种方法，对获取那些会触发回流操作的属性（比如offsetWidth等）尤为重要。</p>
<p>5.当对HTMLCollection对象进行操作时，应该将访问的次数尽可能的降至最低，最简单的，你可以将length属性缓存在一个本地变量中，这样就能大幅度的提高循环的效率。</p><p><br></p><p><strong>二、避免大字符串字面量对象操作，如 字符串.lenth，尽量转换为new String(字符串)后再进行操作</strong></p>
<p><strong>三、在做字符查找替换等操作时善用正则表达式</strong><br>快速掌握ECMAScript正则表达式。参见：<a href="http://www.w3cgroup.com/article.asp?id=202" target="_blank">http://www.w3cgroup.com/article.asp?id=202</a></p>
<p><strong>四、减少语句，利用运算符优先级实现if else表达式，使用三元表达式，使用连续表达式（看情况，将损失程序可读性）</strong></p>
<p>利用运算符优先级实现if else表达式参见：<a href="http://www.w3cgroup.com/article.asp?id=131" target="_blank">http://www.w3cgroup.com/article.asp?id=131</a></p>
<p><strong>五、将CSS，JS文件合并到一个文件</strong>（非BT爱好者还是不要玩了^_^）<br>参见：<a href="http://www.w3cgroup.com/article.asp?id=29" target="_blank">http://www.w3cgroup.com/article.asp?id=29</a></p>
<p><strong>六、避免Javascript事件绑定出现内存泄漏</strong><br>"These memory leaks
often occur as a result of circular references between JavaScript
objects and objects within IE’s DOM (document object model)." Microsoft
GPDE Team Blog</p>
<p>参见：<a href="http://www.w3cgroup.com/article.asp?id=207" target="_blank">http://www.w3cgroup.com/article.asp?id=207</a></p>
<p><strong>七、使用WEB Workers技术（支持html5的浏览器）<br></strong>Web Workers为JavaScript提供了一种能在后台进程中运行的方法，Web Workers进程能够在不影响用户界面的情况下处理任务。</p>
<p>参见：<a href="http://www.w3cgroup.com/article.asp?id=242" target="_blank">http://www.w3cgroup.com/article.asp?id=242</a></p>
<p><strong>八、Y!14条（14 Rules for Faster-Loading Web Sites）</strong></p>
<ul><li>Rule 1 - Make Fewer HTTP Requests</li><li>Rule 2 - Use a Content Delivery Network (Server端)</li><li>Rule 3 - Add an Expires Header (Server端)</li><li>Rule 4 - Gzip Components (Server端)</li><li>Rule 5 - Put Stylesheets at the Top</li><li>Rule 6 - Put Scripts at the Bottom</li><li>Rule 7 - Avoid CSS Expressions</li><li>Rule 8 - Make JavaScript and CSS External</li><li>Rule 9 - Reduce DNS Lookups (Server端)</li><li>Rule 10 - Minify JavaScript</li><li>Rule 11 - Avoid Redirects (Server端)</li><li>&nbsp;Rule 12 - Remove Duplicate Scripts</li><li>Rule 13 - Configure ETags (Server端)</li><li>Rule 14 - Make AJAX Cacheable</li><li>Rule 15 - Use Iframes Wisely</li></ul>
<p>参见：<a href="http://www.w3cgroup.com/article.asp?id=97" target="_blank">http://www.w3cgroup.com/article.asp?id=97</a></p>
<p><strong>九、微软早期的DHTML优化建议</strong></p>
<ul><li>使用数组push替代字符串累加</li></ul>
<p>出处<a href="http://www.w3cgroup.com/article.asp?id=255" target="_blank">http://www.w3cgroup.com/article.asp?id=255</a></p><br></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200951191747234</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200951191747234</guid>
    <pubDate>Thu, 11 Jun 2009 09:17:47 +0800</pubDate>
    <dcterms:modified>2009-06-11T09:17:47+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Javascript面向对象基础以及接口和继承类的实现]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200922744437409</link>
    <description><![CDATA[<div><p>在开始设计模式的书写之前，有必要对Javascript面向对象的概念先做个介绍，那么这篇文章就以面向对象基础作为起点吧。</p>
<p><strong>理论知识</strong></p>
<p>1. 首先Javascript是弱类型语言，它定义变量时不必声明类型，如var Person = new
Person()，它的变量类型为“var”，现在的C#
3.0也引进了这种匿名类型的概念，弱类型的变量产生了极大的灵活性，因为Javascript会根据需要来进行类型转换。所以这也决定了它采用了晚绑定
的方法，即在运行后才知道变量的类型；</p>
<p>2. 面向对象概念不必多说，封装，继承，多态；</p>
<p>3. Javascript对象的类型主要分为三种：本地对象，如String，Array，Date等；内置对象，如Global，Math等；宿主对象，是指传统面向对象程序设计中的作用域，如公有，保护，私有，静态等等。</p>
<p><strong>主要内容</strong></p>
<p>1. 现在让我们来看看Javascript怎样创建对象的：</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>function Man() {<br>   //  <br>}<br>Man.prototype.getNickName = function() {<br>    return "Leepy";<br>}; <br><br>var man = new Man();<br>var name = man.getNickName(); <br></pre></td></tr></tbody></table>
<p>这样就创建了最简单的类和对象，其中我们可以把function Man() {}
看作是Man类的构造函数，getNickName()看作是Man类的方法，准确说可以“当作”是Man类的公共方法；为什么要说是当作呢？那是因为其
实Javascript实际上并没有一个私有共有的划分，因此开发者们自己指定了这样的规约，那么规约是什么样的呢？我这里把Man类的清单完整地列出
来：</p>
<div align="center">
<div style="border: 1px solid rgb(204, 204, 204); padding: 0px 0px 6px 10px; overflow: auto; margin-left: auto; width: 517px; margin-right: auto; height: 166px;">
<p align="left">
</p><div align="left"><pre>function Man() {<br>    // 私有静态属性<br>    var Sex = "男";<br>    //私有静态方法<br>    function checkSex() {<br>        return (Sex == "男");<br>    }<br>    //私有方法<br>    this._getSex = function() {<br>        //调用私有静态方法<br>        if(checkSex())<br>            return "男";<br>        else<br>            return "女";<br>    }<br>    //私有方法<br>    this.getFirstName = function() { <br>        return "Li";<br>    };<br>    //私有方法<br>    this.getLastName = function() {<br>        return "Ping";<br>    };<br>}<br>//公共方法<br>Man.prototype.getNickName = function() {<br>    return "Leepy";<br>};<br>//公共方法<br>Man.prototype.getFullName = function() {<br>    return this.getFirstName() + " " + this.getLastName();<br>};<br>//公共方法<br>Man.prototype.getSex = function() {<br>    //调用私有方法<br>    return this._getSex();<br>};<br>//公共静态方法<br>Man.say = function() {<br>    return "Happy new year!";<br>}<br></pre></div>
</div></div>
<p>这样的类是否看起来和传统的类很相似了呢？</p>
<p>2.接下来这个是本篇的一个重点，就是用Javascript如何设计一个接口，然后让类继承于它。</p>
<p>首先，先让我们看传统的C#语言是如何设计接口的吧：</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>public interface Person<br>{<br>    string GetName();<br>    void SetName(string name);<br>}<br>public class Man : Person<br>{<br>    private string _name; <br><br>    public string GetName()<br>    {<br>        return _name;<br>    }<br>    public void SetName(string name)<br>    {<br>        _name = name;<br>    }<br>} <br></pre></td></tr></tbody></table>
<p>接口中可以声明属性、方法、事件和类型(Structure)，（但不能声明变量），但是并不能设置这些成员的具体值，也就是说，只能定义，不能给
它里面定义的东西赋值，而接口作为它的继承类或者派生类的规约，继承类或者它的派生类能够共同完成接口属性、方法、事件和类型的具体实现，因为这里
GetName()，SetName()，不管是方法名还是属性调用顺序上都是要保持一致的；</p>
<p>那么有了这样的一个基于接口的思想，我们设计Javascript的接口类的时候也需要考虑到这个规范。我先从主JS文件调用端开始说起：</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>var Person = new Interface("Person", [["getName", 0], ["setName", 1]]); <br></pre></td></tr></tbody></table>
<p>其中Interface类是稍后要说的接口类，第一个参数"Person"是接口类的名称，第二个参数是个二维数组，"getName"是接口方法
的名称，"0"是该方法所带的参数个数（因为Javascript是弱语言，所以类型是不确定的，所以只要记住参数个数就好，"0"可以省略不
写），"setName"同理。这样一个接口定义好了。怎样使用它呢？</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>function Man() <br>{<br>    this.name = "";<br>    Interface.registerImplements(this, Person);<br>}<br>Man.prototype.getName = function() {<br>    return this.name;<br>};<br>Man.prototype.setName = function(name) {<br>    this.name = name;<br>}; <br></pre></td></tr></tbody></table>
<p>看到Man的构造函数里面包含</p>
<p><em>Interface.registerImplements(this, Person);</em></p>
<p>它是用来将实例化的this对象继承于Person接口，然后继承类对接口的方法进行实现。</p>
<p>代码看起来是不是很清晰和简单呢，那么现在要开始介绍真正的核心代码Interface.js了：</p>
<p>先看Interface的构造函数部分</p>
<div align="center">
<div style="border: 1px solid rgb(204, 204, 204); padding: 0px 0px 6px 10px; overflow: auto; margin-left: auto; width: 517px; margin-right: auto; height: 166px;">
<p align="left">
</p><div align="left"><pre>unction Interface(name, methods) <br>{<br>    if(arguments.length != 2) {<br>        throw new Error("接口构造函数含" + arguments.length + "个参数, 但需要2个参数.");<br>    }<br>    this.name = name;<br>    this.methods = [];<br>    if(methods.length &lt; 1) {<br>        throw new Error("第二个参数为空数组.");<br>    }<br>    for(var i = 0, len = methods.length; i &lt; len; i++) {<br>        if(typeof methods[i][0] !== 'string') {<br>            throw new Error("接口构造函数第一个参数必须为字符串类型.");<br>        }<br>        if(methods[i][1] &amp;&amp; typeof methods[i][1] !== 'number') {<br>            throw new Error("接口构造函数第二个参数必须为整数类型.");<br>        }<br>        if(methods[i].length == 1) {<br>            methods[i][1] = 0;<br>        } <br><br>        this.methods.push(methods[i]);<br>    }    <br>};<br></pre></div>
</div></div>
<p>刚才看到了var Person = new Interface("Person", [["getName", 0], ["setName", 1]]);，这里将两个参数分别保存起来；<br></p><p><strong>调用方法部分：</strong></p>
<div align="center">
<div style="border: 1px solid rgb(204, 204, 204); padding: 0px 0px 6px 10px; overflow: auto; margin-left: auto; width: 517px; margin-right: auto; height: 166px;">
<p align="left">
</p><div align="left"><pre>Interface.registerImplements = function(object) { <br><br>    if(arguments.length &lt; 2) {<br>        throw new Error("接口的实现必须包含至少2个参数.");<br>    } <br><br>    for(var i = 1, len = arguments.length; i &lt; len; i++) {<br>        var interface = arguments[i];<br>        if(interface.constructor !== Interface) {<br>            throw new Error("从第2个以上的参数必须为接口实例.");<br>        }<br>        for(var j = 0, methodsLen = interface.methods.length; j &lt; methodsLen; j++) {<br>            var method = interface.methods[j][0];<br>            if(!object[method] || typeof object[method] !== 'function' || object[method].getParameters().length != interface.methods[j][1]) {<br>                throw new Error("接口的实现对象不能执行" + interface.name + "的接口方法" + method + "，因为它找不到或者不匹配.");<br>            }<br>        }<br>    }<br>}; <br></pre></div>
</div></div>
<p>刚才这句Interface.registerImplements(this,
Person);，实际上这里是把this对象的方法名以及参数个数与刚Person保存的methods逐一进行比较，如果找不到或者不匹配，就警告错
误；其中object[method].getParameters().length，调用了如下的代码：</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>Function.prototype.getParameters = function() { <br><br>    var str = this.toString();<br>    var paramString = str.slice(str.indexOf('(') + 1, str.indexOf(')')).rep<br>lace(/\s*/g,'');     //取得参数字符串<br>    try<br>    {<br>        return (paramString.length == 0 ? [] : paramString.split(','));<br>    }<br>    catch(err)<br>    {<br>        throw new Error("函数不合法!");<br>    }<br>} <br></pre></td></tr></tbody></table>
<p>getParrameters()方法作为Function对象的一个扩展，功能是取得方法含有的参数数组；</p>
<p>Interface.js完整的代码如下：</p>
<p><strong>Interface.js文件</strong></p>
<div align="center">
<div style="border: 1px solid rgb(204, 204, 204); padding: 0px 0px 6px 10px; overflow: auto; margin-left: auto; width: 517px; margin-right: auto; height: 166px;">
<p align="left">
</p><div align="left"><pre>function Interface(name, methods) <br>{<br>    if(arguments.length != 2) {<br>        throw new Error("接口构造函数含" + arguments.length + "个参数, 但需要2个参数.");<br>    }<br>    this.name = name;<br>    this.methods = [];<br>    if(methods.length &lt; 1) {<br>        throw new Error("第二个参数为空数组.");<br>    }<br>    for(var i = 0, len = methods.length; i &lt; len; i++) {<br>        if(typeof methods[i][0] !== 'string') {<br>            throw new Error("接口构造函数第一个参数必须为字符串类型.");<br>        }<br>        if(methods[i][1] &amp;&amp; typeof methods[i][1] !== 'number') {<br>            throw new Error("接口构造函数第二个参数必须为整数类型.");<br>        }<br>        if(methods[i].length == 1) {<br>            methods[i][1] = 0;<br>        } <br><br>        this.methods.push(methods[i]);<br>    }    <br>}; <br><br>Interface.registerImplements = function(object) { <br><br>    if(arguments.length &lt; 2) {<br>        throw new Error("接口的实现必须包含至少2个参数.");<br>    } <br><br>    for(var i = 1, len = arguments.length; i &lt; len; i++) {<br>        var interface = arguments[i];<br>        if(interface.constructor !== Interface) {<br>            throw new Error("从第2个以上的参数必须为接口实例.");<br>        }<br>        for(var j = 0, methodsLen = interface.methods.length; j &lt; methodsLen; j++) {<br>            var method = interface.methods[j][0];<br>            if(!object[method] || typeof object[method] !== 'function' || object[method].getParameters().length != interface.methods[j][1]) {<br>                throw new Error("接口的实现对象不能执行" + interface.name + "的接口方法" + method + "，因为它找不到或者不匹配.");<br>            }<br>        }<br>    }<br>}; <br><br>Function.prototype.getParameters = function() { <br><br>    var str = this.toString();<br>    var paramString = str.slice(str.indexOf('(') + 1, str.indexOf(')')).replace(/\s*/g,'');     //取得参数字符串<br>    try<br>    {<br>        return (paramString.length == 0 ? [] : paramString.split(','));<br>    }<br>    catch(err)<br>    {<br>        throw new Error("函数不合法!");<br>    }<br>} <br></pre></div>
</div></div>
<p>好了该创建一个html页面来试试效果了：</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>＜script type="text/javascript"＞<br>function test()<br>{<br>    var man = new Man();<br>    man.setName("Leepy");<br>    alert(man.getName());<br>}<br>＜/script＞ <br><br>＜input type="button" value="click" onclick="test();" /＞<br></pre></td></tr></tbody></table>
<p>最终结果为："Leepy"的弹出框。</p>
<p>这里还有一点要强调，如果接口上的方法没有在继承类上得到完全实现，或者方法参数个数不匹配，那么就会提示错误。</p>
<p>3. 如果我要一个类继承于另一个类该怎么做呢，继续看例子，这里我再定义一个SchoolBoy（男学生）类：</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>function SchoolBoy(classNo, post)<br>{<br>    Man.call(this);<br>    this._chassNo = classNo;<br>    this._post = post;<br>}<br>SchoolBoy.prototype = new Man();<br>SchoolBoy.prototype.getName = function() {<br>    return "Mr " + this.name;<br>}<br>SchoolBoy.prototype.setName = function(name) {<br>    this.name = name + "'s";<br>}<br></pre></td></tr></tbody></table>
<p>其中Man.call(this);实际上是将Man中的关键字this赋值于SchoolBoy对象中去，那么SchoolBoy就拥有了Man构造函数中的name属性了。</p>
<p>SchoolBoy.prototype = new Man();实际上是把Man的prototype赋值给SchoolBoy.prototype，那么SchoolBoy就有了Man类中的方法。</p>
<p>而后面跟着的getName()，setName()，实际上是覆盖了前面继承于Man类中的方法了。</p>
<p>然后看看效果：</p>
<table bordercolordark="#ffffff" bordercolorlight="#999999" width="400" align="center" border="1" cellpadding="2" cellspacing="0">
<tbody>
<tr>
<td  bgcolor="#e6e6e6"><pre>var schoolboy = new SchoolBoy("三年二班", "班长");<br>schoolboy.setName("周杰伦");<br>alert(schoolboy.getName());<br></pre></td></tr></tbody></table>
<p>最后结果为："Mr 周杰伦's"的弹出框。</p><p><br></p></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200922744437409</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200922744437409</guid>
    <pubDate>Fri, 27 Mar 2009 16:44:37 +0800</pubDate>
    <dcterms:modified>2009-03-28T11:01:45+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[ javascript 正则表达式祥解]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/24753220092242850730</link>
    <description><![CDATA[<div>转<br><p>正则表达式使用详解<br>简介</p>
<p>简单的说，正则表达式是一种可以用于模式匹配和替换的强有力的工具。其作用如下：<br>测试字符串的某个模式。例如，可以对一个输入字符串进行测试，看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证。<br>替换文本。可以在文档中使用一个正则表达式来标识特定文字，然后可以全部将其删除，或者替换为别的文字。<br>根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字。</p>
<p>基本语法</p>
<p>在对正则表达式的功能和作用有了初步的了解之后，我们就来具体看一下正则表达式的语法格式。<br>正则表达式的形式一般如下：　　</p>
<p>/love/　　其中位于“/”定界符之间的部分就是将要在目标对象中进行匹配的模式。用户只要把希望查找匹配对象的模式内容放入“/”定界符之间
即可。为了能够使用户更加灵活的定制模式内容，正则表达式提供了专门的“元字符”。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符，可以用来
规定其前导字符（即位于元字符前面的字符）在目标对象中的出现模式。<br>较为常用的元字符包括： “+”， “*”，以及 “?”。</p>
<p>“+”元字符规定其前导字符必须在目标对象中连续出现一次或多次。</p>
<p>“*”元字符规定其前导字符必须在目标对象中出现零次或连续多次。</p>
<p>“?”元字符规定其前导对象必须在目标对象中连续出现零次或一次。</p>
<p>下面，就让我们来看一下正则表达式元字符的具体应用。</p>
<p>/fo+/　　因为上述正则表达式中包含“+”元字符，表示可以与目标对象中的 “fool”, “fo”, 或者 “football”等在字母f后面连续出现一个或多个字母o的字符串相匹配。</p>
<p>/eg*/　　因为上述正则表达式中包含“*”元字符，表示可以与目标对象中的 “easy”, “ego”, 或者 “egg”等在字母e后面连续出现零个或多个字母g的字符串相匹配。</p>
<p>/Wil?/　　因为上述正则表达式中包含“？”元字符，表示可以与目标对象中的 “Win”, 或者“Wilson”,等在字母i后面连续出现零个或一个字母l的字符串相匹配。</p>
<p>有时候不知道要匹配多少字符。为了能适应这种不确定性，正则表达式支持限定符的概念。这些限定符可以指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。</p>
<p>{n} n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</p>
<p>{n,} n 是一个非负整数。至少匹配 n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</p>
<p>{n,m} m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</p>
<p>除了元字符之外，用户还可以精确指定模式在匹配对象中出现的频率。例如，/jim {2,6}/ 上述正则表达式规定字符m可以在匹配对象中连续出现2-6次，因此，上述正则表达式可以同jimmy或jimmmmmy等字符串相匹配。<br>在对如何使用正则表达式有了初步了解之后，我们来看一下其它几个重要的元字符的使用方式。<br>代码</p>
<p>&nbsp;&nbsp; 1. \s：用于匹配单个空格符，包括tab键和换行符；&nbsp;&nbsp; <br>&nbsp;&nbsp; 2. \S：用于匹配除单个空格符之外的所有字符；&nbsp;&nbsp; <br>&nbsp;&nbsp; 3. \d：用于匹配从0到9的数字；&nbsp;&nbsp; <br>&nbsp;&nbsp; 4. \w：用于匹配字母，数字或下划线字符；&nbsp;&nbsp; <br>&nbsp;&nbsp; 5. \W：用于匹配所有与\w不匹配的字符；&nbsp;&nbsp; <br>&nbsp;&nbsp; 6. . ：用于匹配除换行符之外的所有字符。&nbsp;&nbsp; </p>
<p><br>（说明：我们可以把\s和\S以及\w和\W看作互为逆运算）<br>下面，我们就通过实例看一下如何在正则表达式中使用上述元字符。<br>/\s+/ 上述正则表达式可以用于匹配目标对象中的一个或多个空格字符。<br>/\d000/　如果我们手中有一份复杂的财务报表，那么我们可以通过上述正则表达式轻而易举的查找到所有总额达千元的款项。<br>除了我们以上所介绍的元字符之外，正则表达式中还具有另外一种较为独特的专用字符，即定位符。定位符用于规定匹配模式在目标对象中的出现位置。 较为常用的定位符包括： “^”, “$”, “\b” 以及 “\B”。<br>代码</p>
<p>&nbsp;&nbsp; 1. “^”定位符规定匹配模式必须出现在目标字符串的开头&nbsp; <br>&nbsp;&nbsp; 2. “$”定位符规定匹配模式必须出现在目标对象的结尾&nbsp; <br>&nbsp;&nbsp; 3. “\b”定位符规定匹配模式必须出现在目标字符串的开头或结尾的两个边界之一&nbsp; <br>&nbsp;&nbsp; 4. “\B”定位符则规定匹配对象必须位于目标字符串的开头和结尾两个边界之内，&nbsp; <br>&nbsp;&nbsp; 5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 即匹配对象既不能作为目标字符串的开头，也不能作为目标字符串的结尾。&nbsp; </p>
<p><br>同样，我们也可以把“^”和“$”以及“\b”和“\B”看作是互为逆运算的两组定位符。举例来说：
/^hell/　因为上述正则表达式中包含“^”定位符，所以可以与目标对象中以 “hell”,
“hello”或“hellhound”开头的字符串相匹配。 /ar$/　因为上述正则表达式中包含“$”定位符，所以可以与目标对象中以
“car”, “bar”或 “ar” 结尾的字符串相匹配。 /\bbom/　因为上述正则表达式模式以“\b”定位符开头，所以可以与目标对象中以
“bomb”, 或 “bom”开头的字符串相匹配。/man\b/　因为上述正则表达式模式以“\b”定位符结尾，所以可以与目标对象中以
“human”, “woman”或 “man”结尾的字符串相匹配。<br>为了能够方便用户更加灵活的设定匹配模式，正则表达式允许使用者在匹配模式中指定某一个范围而不局限于具体的字符。例如：<br>代码</p>
<p>&nbsp;&nbsp; 1. /[A-Z]/　　上述正则表达式将会与从A到Z范围内任何一个大写字母相匹配。&nbsp; <br>&nbsp;&nbsp; 2. /[a-z]/　　上述正则表达式将会与从a到z范围内任何一个小写字母相匹配。&nbsp;&nbsp; <br>&nbsp;&nbsp; 3. /[0-9]/ 　上述正则表达式将会与从0到9范围内任何一个数字相匹配。&nbsp;&nbsp; <br>&nbsp;&nbsp; 4. /([a-z][A-Z][0-9])+/　上述正则表达式将会与任何由字母和数字组成的字符串，如 “aB0” 等相匹配。&nbsp; </p>
<p><br>这里需要提醒用户注意的一点就是可以在正则表达式中使用 “()” 把字符串组合在一起。“()”符号包含的内容必须同时出现在目标对象中。因此，上述正则表达式将无法与诸如 “abc”等的字符串匹配，因为“abc”中的最后一个字符为字母而非数字。<br>如果我们希望在正则表达式中实现类似编程逻辑中的“或”运算，在多个不同的模式中任选一个进行匹配的话，可以使用管道符 “|”。例如：/to|too|2/　上述正则表达式将会与目标对象中的 “to”, “too”, 或 “2” 相匹配。<br>正
则表达式中还有一个较为常用的运算符，即否定符 “[^]”。与我们前文所介绍的定位符 “^” 不同，否定符
“[^]”规定目标对象中不能存在模式中所规定的字符串。例如：/[^A-C]/　上述字符串将会与目标对象中除A，B，和C之外的任何字符相匹配。一般
来说，当“^”出现在 “[]”内时就被视做否定运算符；而当“^”位于“[]”之外，或没有“[]”时，则应当被视做定位符。<br>最后，当用户需要在正则表达式的模式中加入元字符，并查找其匹配对象时，可以使用转义符“\”。例如：/Th\*/ 　上述正则表达式将会与目标对象中的“Th*”而非“The”等相匹配。<br>在构造正则表达式之后，就可以象数学表达式一样来求值，也就是说，可以从左至右并按照一个优先级顺序来求值。优先级如下：<br>代码</p>
<p>&nbsp;&nbsp; 1. 1．\ 转义符&nbsp; <br>&nbsp;&nbsp; 2. 2．(), (?, (?=), [] 圆括号和方括号&nbsp; <br>&nbsp;&nbsp; 3. 3．*, +, ?, {n}, {n,}, {n,m} 限定符&nbsp; <br>&nbsp;&nbsp; 4. 4．^, $, \anymetacharacter 位置和顺序&nbsp; <br>&nbsp;&nbsp; 5. 5．|“或”操作&nbsp; </p>
<p>使用实例<br>在JavaScript 1.2中带有一个功能强大的RegExp()对象，可以用来进行正则表达式的匹配操作。其中的test()方法可以检验目标对象中是否包含匹配模式，并相应的返回true或false。<br>我们可以使用JavaScript编写以下脚本，验证用户输入的邮件地址的有效性。<br>代码</p>
<p>&nbsp;&nbsp; 1. &lt;html&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp; 2. &lt;head&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp; 3. 　 &lt;script language="Javascript1.2"&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp; 4. 　　　　 &lt;!-- start hiding&nbsp;&nbsp; <br>&nbsp;&nbsp; 5. 　　　　 function verifyAddress(obj)&nbsp;&nbsp; <br>&nbsp;&nbsp; 6. 　　　　　{&nbsp;&nbsp; <br>&nbsp;&nbsp; 7. 　　　　　　var email = obj.email.value;&nbsp;&nbsp; <br>&nbsp;&nbsp; 8. 　　　　　　var pattern =&nbsp;&nbsp; <br>&nbsp;&nbsp; 9. /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;&nbsp;&nbsp; <br>&nbsp; 10. 　　　　　　flag = pattern.test(email);&nbsp;&nbsp; <br>&nbsp; 11. 　　　　　　if(flag)&nbsp;&nbsp; <br>&nbsp; 12. 　　　　　　{&nbsp;&nbsp; <br>&nbsp; 13. 　　　　　　　alert(“Your email address is correct!”);&nbsp;&nbsp; <br>&nbsp; 14. 　　　　　　　return true;&nbsp;&nbsp; <br>&nbsp; 15. 　　　　　　}&nbsp;&nbsp; <br>&nbsp; 16. 　　　　　　else&nbsp;&nbsp; <br>&nbsp; 17. 　　　　　　　{&nbsp;&nbsp; <br>&nbsp; 18. 　　　　　　　　alert(“Please try again!”);&nbsp;&nbsp; <br>&nbsp; 19. 　　　　　　　　return false;&nbsp;&nbsp; <br>&nbsp; 20. 　　　　　　　 }&nbsp;&nbsp; <br>&nbsp; 21. 　　　　　 }&nbsp;&nbsp; <br>&nbsp; 22. 　　　　 // stop hiding --&gt;&nbsp;&nbsp; <br>&nbsp; 23. 　　　 &lt;/script&gt;&nbsp;&nbsp; <br>&nbsp; 24. 　　&lt;/head&gt;&nbsp;&nbsp; <br>&nbsp; 25. 　 &lt;body&gt;&nbsp;&nbsp; <br>&nbsp; 26. 　　 &lt;form onSubmit="return verifyAddress(this);"&gt;&nbsp;&nbsp; <br>&nbsp; 27. 　　　 &lt;input name="email" type="text"&gt;&nbsp;&nbsp; <br>&nbsp; 28. 　　　 &lt;input type="submit"&gt;&nbsp;&nbsp; <br>&nbsp; 29. 　　　 &lt;/form&gt;&nbsp;&nbsp; <br>&nbsp; 30. 　　&lt;/body&gt;&nbsp;&nbsp; <br>&nbsp; 31. &lt;/html&gt; <br>&nbsp;</p>
<p>JS的正则表达式</p>
<p>//校验是否全由数字组成<br>代码</p>
<p>&nbsp;&nbsp; 1. function isDigit(s)&nbsp; <br>&nbsp;&nbsp; 2. {&nbsp; <br>&nbsp;&nbsp; 3. var patrn=/^[0-9]{1,20}$/;&nbsp; <br>&nbsp;&nbsp; 4. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp;&nbsp; 5. return true&nbsp; <br>&nbsp;&nbsp; 6. }&nbsp; </p>
<p>//校验登录名：只能输入5-20个以字母开头、可带数字、“_”、“.”的字串<br>代码</p>
<p>&nbsp;&nbsp; 1. function isRegisterUserName(s)&nbsp; <br>&nbsp;&nbsp; 2. {&nbsp; <br>&nbsp;&nbsp; 3. var patrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;&nbsp; <br>&nbsp;&nbsp; 4. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp;&nbsp; 5. return true&nbsp; <br>&nbsp;&nbsp; 6. }&nbsp; </p>
<p>//校验用户姓名：只能输入1-30个以字母开头的字串<br>代码</p>
<p>&nbsp;&nbsp; 1. function isTrueName(s)&nbsp; <br>&nbsp;&nbsp; 2. {&nbsp; <br>&nbsp;&nbsp; 3. var patrn=/^[a-zA-Z]{1,30}$/;&nbsp; <br>&nbsp;&nbsp; 4. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp;&nbsp; 5. return true&nbsp; <br>&nbsp;&nbsp; 6. }&nbsp; <br>&nbsp;&nbsp; 7. }}&nbsp; <br>&nbsp;&nbsp; 8.&nbsp;&nbsp; <br>&nbsp;&nbsp; 9. //校验密码：只能输入6-20个字母、数字、下划线&nbsp; <br>&nbsp; 10. [code]&nbsp; <br>&nbsp; 11. function isPasswd(s)&nbsp; <br>&nbsp; 12. {&nbsp; <br>&nbsp; 13. var patrn=/^(\w){6,20}$/;&nbsp; <br>&nbsp; 14. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp; 15. return true&nbsp; <br>&nbsp; 16. }&nbsp; </p>
<p>//校验普通电话、传真号码：可以“+”开头，除数字外，可含有“-”<br>代码</p>
<p>&nbsp;&nbsp; 1. function isTel(s)&nbsp; <br>&nbsp;&nbsp; 2. {&nbsp; <br>&nbsp;&nbsp; 3. //var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?(\d){1,12})+$/;&nbsp; <br>&nbsp;&nbsp; 4. var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;&nbsp; <br>&nbsp;&nbsp; 5. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp;&nbsp; 6. return true&nbsp; <br>&nbsp;&nbsp; 7. }&nbsp; </p>
<p>//校验手机号码：必须以数字开头，除数字外，可含有“-”<br>代码</p>
<p>&nbsp;&nbsp; 1. function isMobil(s)&nbsp; <br>&nbsp;&nbsp; 2. {&nbsp; <br>&nbsp;&nbsp; 3. var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;&nbsp; <br>&nbsp;&nbsp; 4. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp;&nbsp; 5. return true&nbsp; <br>&nbsp;&nbsp; 6. }&nbsp; </p>
<p>//校验邮政编码<br>代码</p>
<p>&nbsp;&nbsp; 1. function isPostalCode(s)&nbsp; <br>&nbsp;&nbsp; 2. {&nbsp; <br>&nbsp;&nbsp; 3. //var patrn=/^[a-zA-Z0-9]{3,12}$/;&nbsp; <br>&nbsp;&nbsp; 4. var patrn=/^[a-zA-Z0-9 ]{3,12}$/;&nbsp; <br>&nbsp;&nbsp; 5. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp;&nbsp; 6. return true&nbsp; <br>&nbsp;&nbsp; 7. }&nbsp; </p>
<p>//校验搜索关键字<br>代码</p>
<p>&nbsp;&nbsp; 1. function isSearch(s)&nbsp; <br>&nbsp;&nbsp; 2. {&nbsp; <br>&nbsp;&nbsp; 3. var patrn=/^[^`~!@#$%^&amp;*()+=|\\\][\]\{\}:;'\,.&lt;&gt;/?]{1}[^`~!@$%^&amp;()+=|\\\]&nbsp; <br>&nbsp;&nbsp; 4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [\]\{\}:;'\,.&lt;&gt;?]{0,19}$/;&nbsp; <br>&nbsp;&nbsp; 5. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp;&nbsp; 6. return true&nbsp; <br>&nbsp;&nbsp; 7. }&nbsp; <br>&nbsp;&nbsp; 8.&nbsp;&nbsp; <br>&nbsp;&nbsp; 9. function isIP(s) //by zergling&nbsp; <br>&nbsp; 10. {&nbsp; <br>&nbsp; 11. var patrn=/^[0-9.]{1,20}$/;&nbsp; <br>&nbsp; 12. if (!patrn.exec(s)) return false&nbsp; <br>&nbsp; 13. return true&nbsp; <br>&nbsp; 14. }&nbsp; </p>
<p>正则表达式<br>代码</p>
&nbsp;&nbsp; 1. "^\\d+$"　　//非负整数（正整数 + 0）&nbsp; <br>&nbsp;&nbsp; 2. "^[0-9]*[1-9][0-9]*$"　　//正整数&nbsp;&nbsp; <br>&nbsp;&nbsp; 3. "^((-\\d+)|(0+))$"　　//非正整数（负整数 + 0）&nbsp;&nbsp; <br>&nbsp;&nbsp; 4. "^-[0-9]*[1-9][0-9]*$"　　//负整数&nbsp;&nbsp; <br>&nbsp;&nbsp; 5. "^-?\\d+$"　　　　//整数&nbsp;&nbsp; <br>&nbsp;&nbsp; 6. "^\\d+(<a href="/file://%5c%5c.%5c%5cd+%29?$/">\\.\\d+)?$</a>"　　//非负浮点数（正浮点数 + 0）&nbsp;&nbsp; <br>&nbsp;&nbsp; 7. "^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$"　&nbsp; <br>&nbsp;&nbsp; 8. //正浮点数&nbsp;&nbsp; <br>&nbsp;&nbsp; 9. "^((-\\d+(<a href="/file://%5c%5c.%5c%5cd+%29?%29%7c%280+%28%5c%5c.0+%29?%29%29$/">\\.\\d+)?)|(0+(\\.0+)?))$</a>"　　//非正浮点数（负浮点数 + 0）&nbsp;&nbsp; <br>&nbsp; 10. "^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"　&nbsp; <br>&nbsp; 11. //负浮点数&nbsp;&nbsp; <br>&nbsp; 12. "^(-?\\d+)(<a href="/file://%5c%5c.%5c%5cd+%29?$/">\\.\\d+)?$</a>"　　//浮点数&nbsp;&nbsp; <br>&nbsp; 13. "^[A-Za-z]+$"　　//由26个英文字母组成的字符串&nbsp;&nbsp; <br>&nbsp; 14. "^[A-Z]+$"　　//由26个英文字母的大写组成的字符串&nbsp;&nbsp; <br>&nbsp; 15. "^[a-z]+$"　　//由26个英文字母的小写组成的字符串&nbsp;&nbsp; <br>&nbsp; 16. "^[A-Za-z0-9]+$"　　//由数字和26个英文字母组成的字符串&nbsp;&nbsp; <br>&nbsp; 17. "^\\w+$"　　//由数字、26个英文字母或者下划线组成的字符串&nbsp;&nbsp; <br>&nbsp; 18. "^[\\w-]+(<a href="/file://%5c%5c.%5b%5c%5cw-%5d+%29*@%5b%5c%5cw-%5d+%28%5c%5c.%5b%5c%5cw-%5d+%29+$/">\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$</a>"　　　　//email地址&nbsp;&nbsp; <br>&nbsp; 19. "^[a-zA-z]+://(<a href="/file://%5c%5cw+%28-%5c%5cw+%29*%29%28%5c%5c.%28%5c%5cw+%28-%5c%5cw+%29*%29%29*%28%5c%5c?%5c%5cs*%29?$/">\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$</a>"　　//url&nbsp; <br>&nbsp; 20. "^[A-Za-z0-9_]*$" <br></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/24753220092242850730</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/24753220092242850730</guid>
    <pubDate>Tue, 24 Mar 2009 14:08:50 +0800</pubDate>
    <dcterms:modified>2009-03-24T14:08:50+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Javascript 闭包]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200924104025828</link>
    <description><![CDATA[<div><UL>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clIntro">简介</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clResO">基于对象的属性名解析</A> 
<UL>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clResA">值的指定</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clResR">值的读取</A></LI></UL></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clIRExSc">标识符解析、执行环境和作用域链</A> 
<UL>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clExCon">执行环境</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clScCh">作用域链与 [[scope]]</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clIdRes">标识符解析</A></LI></UL></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clClose">闭包</A> 
<UL>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clAtGb">自动垃圾收集</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clFrmC">构成闭包</A></LI></UL></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clClDo">通过闭包可以做什么？</A> 
<UL>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clSto">例 1：为函数引用设置延时</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clObjI">例 2：通过对象实例方法关联函数</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clEncap">例 3：包装相关的功能</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clOtE">其他例子</A></LI></UL></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clAc">意外的闭包</A></LI>
<LI><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#clMem">Internet Explorer 的内在泄漏问题</A></LI></UL>
<H2><A   ><BLOCKQUOTE cite=http://groups.google.com/groups?selm=wu535hos.fsf@hotpop.com>
<DL>
<DT><A   ><DD>所谓“闭包”，指的是一个拥有许多变量和绑定了这些变量的环境的表达式（通常是一个函数），因而这些变量也是该表达式的一部分。 </DD>
<DD></DD></A></DT></DL></BLOCKQUOTE>
</A><P>闭包是 ECMAScript （JavaScript）最强大的特性之一，但用好闭包的前提是必须理解闭包。闭包的创建相对容易，人们甚至会在不经意间创建闭包，但这些无意创建的闭包却存在潜在的危害，尤其是在比较常见的浏览器环境下。如果想要扬长避短地使用闭包这一特性，则必须了解它们的工作机制。而闭包工作机制的实现很大程度上有赖于标识符（或者说对象属性）解析过程中作用域的角色。 </P>
<P>关于闭包，最简单的描述就是 ECMAScript 允许使用内部函数－－即函数定义和函数表达式位于另一个函数的函数体内。而且，这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时，就会形成闭包。也就是说，内部函数会在外部函数返回后被执行。而当这个内部函数执行时，它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明（最初时）的值是外部函数返回时的值，但也会受到内部函数的影响。 </P>
<P>遗憾的是，要适当地理解闭包就必须理解闭包背后运行的机制，以及许多相关的技术细节。虽然本文的前半部分并没有涉及 ECMA 262 规范指定的某些算法，但仍然有许多无法回避或简化的内容。对于个别熟悉对象属性名解析的人来说，可以跳过相关的内容，但是除非你对闭包也非常熟悉，否则最好是不要跳过下面几节。 </P>
</H2><H2><A   ></A><P>ECMAScript 认可两类对象：原生（Native）对象和宿主（Host）对象，其中宿主对象包含一个被称为内置对象的原生对象的子类（ECMA 262 3rd Ed Section 4.3）。原生对象属于语言，而宿主对象由环境提供，比如说可能是文档对象、DOM 等类似的对象。 </P>
<P>原生对象具有松散和动态的命名属性（对于某些实现的内置对象子类别而言，动态性是受限的－－但这不是太大的问题）。对象的命名属性用于保存值，该值可以是指向另一个对象（Objects）的引用（在这个意义上说，函数也是对象），也可以是一些基本的数据类型，比如：String、Number、 Boolean、Null 或 Undefined。其中比较特殊的是 Undefined 类型，因为可以给对象的属性指定一个 Undefined 类型的值，而不会删除对象的相应属性。而且，该属性只是保存着 <CODE>undefined</CODE> 值。 </P>
<P>下面简要介绍一下如何设置和读取对象的属性值，并最大程度地体现相应的内部细节。 </P>
</H2><H3><A   ></A><P>对象的命名属性可以通过为该命名属性赋值来创建，或重新赋值。即，对于： </P><PRE>var objectRef = new Object(); <SPAN javascript 对象。></SPAN>
</PRE>
<P>可以通过下面语句来创建名为 “testNumber” 的属性： </P><PRE>objectRef.testNumber = 5;
<SPAN - 或- */></SPAN>
objectRef["testNumber"] = 5;
</PRE>
<P>在赋值之前，对象中没有“testNumber” 属性，但在赋值后，则创建一个属性。之后的任何赋值语句都不需要再创建这个属性，而只会重新设置它的值： </P><PRE>objectRef.testNumber = 8;
<SPAN - 或- */></SPAN>
objectRef["testNumber"] = 8;
</PRE>
<P>稍后我们会介绍，Javascript 对象都有原型（prototypes）属性，而这些原型本身也是对象，因而也可以带有命名的属性。但是，原型对象命名属性的作用并不体现在赋值阶段。同样，在将值赋给其命名属性时，如果对象没有该属性则会创建该命名属性，否则会重设该属性的值。 </P>
</H3><H3><A   ></A><P>当读取对象的属性值时，原型对象的作用便体现出来。如果对象的原型中包含属性访问器（property accessor）所使用的属性名，那么该属性的值就会返回： </P><PRE><SPAN 为命名属性赋值。如果在赋值前对象没有相应的属性，那么赋值后就会得到一个：*/></SPAN>
objectRef.testNumber = 8;

<SPAN 从属性中读取值 */></SPAN>

var val = objectRef.testNumber;
<SPAN 现在， - val - 中保存着刚赋给对象命名属性的值 8*/></SPAN>
   </PRE>
<P>而且，由于所有对象都有原型，而原型本身也是对象，所以原型也可能有原型，这样就构成了所谓的原型链。原型链终止于链中原型为 null 的对象。<CODE>Object</CODE> 构造函数的默认原型就有一个 null 原型，因此： </P><PRE>var objectRef = new Object(); <SPAN JavaScript 对象。></SPAN>
</PRE>
<P>创建了一个原型为 <CODE>Object.prototype</CODE> 的对象，而该原型自身则拥有一个值为 null 的原型。也就是说，<CODE>objectRef</CODE> 的原型链中只包含一个对象－－ <CODE>Object.prototype</CODE>。但对于下面的代码而言： </P><PRE><SPAN 创建 - MyObject1 - 类型对象的函数*/></SPAN>
function MyObject1(formalParameter){
    <SPAN 给创建的对象添加一个名为 - testNumber -          的属性并将传递给构造函数的第一个参数指定为该属性的值：*/></SPAN>
    this.testNumber = formalParameter;
}

<SPAN 创建 - MyObject2 - 类型对象的函数*/></SPAN>
function MyObject2(formalParameter){
   <SPAN 给创建的对象添加一个名为 - testString -         的属性并将传递给构造函数的第一个参数指定为该属性的值：*/></SPAN>
    this.testString = formalParameter;
}

<SPAN   ></SPAN>
MyObject2.prototype = new MyObject1( 8 );

<SPAN   ></SPAN>

var objectRef = new MyObject2( "String_Value" );
</PRE>
<P>被变量 <CODE>objectRef</CODE> 所引用的 <CODE>MyObject2</CODE> 的实例拥有一个原型链。该链中的第一个对象是在创建后被指定给 <CODE>MyObject2</CODE> 构造函数的 prototype 属性的 <CODE>MyObject1</CODE> 的一个实例。<CODE>MyObject1</CODE> 的实例也有一个原型，即与 <CODE>Object.prototype</CODE> 所引用的对象对应的默认的 Object 对象的原型。最后， <CODE>Object.prototype</CODE> 有一个值为 null 的原型，因此这条原型链到此结束。 </P>
<P>当某个属性访问器尝试读取由 <CODE>objectRef</CODE> 所引用的对象的属性值时，整个原型链都会被搜索。在下面这种简单的情况下： </P><PRE>var val = objectRef.testString;
</PRE>
<P>因为 <CODE>objectRef</CODE> 所引用的 <CODE>MyObject2</CODE> 的实例有一个名为“testString”的属性，因此被设置为“String_Value”的该属性的值被赋给了变量 <CODE>val</CODE>。但是： </P><PRE>var val = objectRef.testNumber;
</PRE>
<P>则不能从 <CODE>MyObject2</CODE> 实例自身中读取到相应的命名属性值，因为该实例没有这个属性。然而，变量 <CODE>val</CODE> 的值仍然被设置为 <CODE>8</CODE>，而不是未定义－－这是因为在该实例中查找相应的命名属性失败后，解释程序会继续检查其原型对象。而该实例的原型对象是 <CODE>MyObject1</CODE> 的实例，这个实例有一个名为“testNumber”的属性并且值为 <CODE>8</CODE>，所以这个属性访问器最后会取得值 <CODE>8</CODE>。而且，虽然 <CODE>MyObject1</CODE> 和 <CODE>MyObject2</CODE> 都没有定义 <CODE>toString</CODE> 方法，但是当属性访问器通过 <CODE>objectRef</CODE> 读取 <CODE>toString</CODE> 属性的值时： </P><PRE>var val = objectRef.toString;
</PRE>
<P>变量 <CODE>val</CODE> 也会被赋予一个函数的引用。这个函数就是在 <CODE>Object.prototype</CODE> 的 <CODE>toString</CODE> 属性中所保存的函数。之所以会返回这个函数，是因为发生了搜索<CODE>objectRef</CODE> 原型链的过程。当在作为对象的 <CODE>objectRef</CODE> 中发现没有“toString”属性存在时，会搜索其原型对象，而当原型对象中不存在该属性时，则会继续搜索原型的原型。而原型链中最终的原型是 <CODE>Object.prototype</CODE>，这个对象确实有一个 <CODE>toString</CODE> 方法，因此该方法的引用被返回。 </P>
<P>最后： </P><PRE>var val = objectRef.madeUpProperty;
</PRE>
<P>返回 <CODE>undefined</CODE>，因为在搜索原型链的过程中，直至 <CODE>Object.prototype</CODE> 的原型－－null，都没有找到任何对象有名为“madeUpPeoperty”的属性，因此最终返回 <CODE>undefined</CODE>。 </P>
<P>不论是在对象或对象的原型中，读取命名属性值的时候只返回首先找到的属性值。而当为对象的命名属性赋值时，如果对象自身不存在该属性则创建相应的属性。 </P>
<P>这意味着，如果执行像 <CODE>objectRef.testNumber = 3</CODE> 这样一条赋值语句，那么这个 <CODE>MyObject2</CODE> 的实例自身也会创建一个名为“testNumber”的属性，而之后任何读取该命名属性的尝试都将获得相同的新值。这时候，属性访问器不会再进一步搜索原型链，但 <CODE>MyObject1</CODE> 实例值为 <CODE>8</CODE> 的“testNumber”属性并没有被修改。给 <CODE>objectRef</CODE> 对象的赋值只是遮挡了其原型链中相应的属性。 </P>
<P>注意：ECMAScript 为 Object 类型定义了一个内部 <CODE>[[prototype]]</CODE> 属性。这个属性不能通过脚本直接访问，但在属性访问器解析过程中，则需要用到这个内部 <CODE>[[prototype]]</CODE> 属性所引用的对象链－－即原型链。可以通过一个公共的 <CODE>prototype</CODE> 属性，来对与内部的 <CODE>[[prototype]]</CODE> 属性对应的原型对象进行赋值或定义。这两者之间的关系在 ECMA 262（3rd edition）中有详细描述，但超出了本文要讨论的范畴。 </P>
</H3><H2><A   ><H3><A   ></A><P>执行环境是 ECMAScript 规范（ECMA 262 第 3 版）用于定义 ECMAScript 实现必要行为的一个抽象的概念。对如何实现执行环境，规范没有作规定。但由于执行环境中包含引用规范所定义结构的相关属性，因此执行环境中应该保有（甚至实现）带有属性的对象－－即使属性不是公共属性。 </P>
<P>所有 JavaScript 代码都是在一个执行环境中被执行的。全局代码（作为内置的 JS 文件执行的代码，或者 <SPAN title="HyperText Mark-up Language"><ABBR title="HyperText Mark-up Language">HTML</ABBR></SPAN> 页面加载的代码）是在我将称之为“全局执行环境”的执行环境中执行的，而对函数的每次调用（有可能是作为构造函数）同样有关联的执行环境。通过 <CODE>eval</CODE> 函数执行的代码也有截然不同的执行环境，但因为 JavaScript 程序员在正常情况下一般不会使用 <CODE>eval</CODE>，所以这里不作讨论。有关执行环境的详细说明请参阅 ECMA 262（第 3 版）第 10.2 节。 </P>
<P>当调用一个 JavaScript 函数时，该函数就会进入相应的执行环境。如果又调用了另外一个函数（或者递归地调用同一个函数），则又会创建一个新的执行环境，并且在函数调用期间执行过程都处于该环境中。当调用的函数返回后，执行过程会返回原始执行环境。因而，运行中的 JavaScript 代码就构成了一个执行环境栈。 </P>
<P>在创建执行环境的过程中，会按照定义的先后顺序完成一系列操作。首先，在一个函数的执行环境中，会创建一个“活动”对象。活动对象是规范中规定的另外一种机制。之所以称之为对象，是因为它拥有可访问的命名属性，但是它又不像正常对象那样具有原型（至少没有预定义的原型），而且不能通过 JavaScript 代码直接引用活动对象。 </P>
<P>为函数调用创建执行环境的下一步是创建一个 <CODE>arguments</CODE> 对象，这是一个类似数组的对象，它以整数索引的数组成员一一对应地保存着调用函数时所传递的参数。这个对象也有 <CODE>length</CODE> 和 <CODE>callee</CODE> 属性（这两个属性与我们讨论的内容无关，详见规范）。然后，会为活动对象创建一个名为“arguments”的属性，该属性引用前面创建的 <CODE>arguments</CODE> 对象。 </P>
<P>接着，为执行环境分配作用域。作用域由对象列表（链）组成。每个函数对象都有一个内部的 <CODE>[[scope]]</CODE> 属性（该属性我们稍后会详细介绍），这个属性也由对象列表（链）组成。指定给一个函数调用执行环境的作用域，由该函数对象的 <CODE>[[scope]]</CODE> 属性所引用的对象列表（链）组成，同时，活动对象被添加到该对象列表的顶部（链的前端）。 </P>
<P>之后会发生由 ECMA 262 中所谓“可变”对象完成的“变量实例化”的过程。只不过此时使用活动对象作为可变对象（这里很重要，请注意：它们是同一个对象）。此时会将函数的形式参数创建为可变对象命名属性，如果调用函数时传递的参数与形式参数一致，则将相应参数的值赋给这些命名属性（否则，会给命名属性赋 <CODE>undefined</CODE> 值）。对于定义的内部函数，会以其声明时所用名称为可变对象创建同名属性，而相应的内部函数则被创建为函数对象并指定给该属性。变量实例化的最后一步是将在函数内部声明的所有局部变量创建为可变对象的命名属性。 </P>
<P>根据声明的局部变量创建的可变对象的属性在变量实例化过程会被赋予 <CODE>undefined</CODE> 值。在执行函数体内的代码、并计算相应的赋值表达式之前不会对局部变量执行真正的实例化。 </P>
<P>事实上，拥有 <CODE>arguments</CODE> 属性的活动对象和拥有与函数局部变量对应的命名属性的可变对象是同一个对象。因此，可以将标识符 <CODE>arguments</CODE> 作为函数的局部变量来看待。 </P><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#">回到顶部</A> 
<P>最后，在this可以被使用之前，还必须先对其赋值。如果赋的值是一个对象的引用，则 this.m 访问的便是该对象上的 m。如果（内部）赋的值是 null，则this就指向全局对象。 （此段由 <A href="http://blog.csdn.net/pongba">pangba 刘未鹏</A> 翻译） </P>
<P a value is assigned for use with the this keyword. If the value assigned refers to an object then property accessors prefixed with the this keyword reference properties of that object. If the value assigned (internally) is null then the this keyword will refer to the global object. ） ></P>
<P>创建全局执行环境的过程会稍有不同，因为它没有参数，所以不需要通过定义的活动对象来引用这些参数。但全局执行环境也需要一个作用域，而它的作用域链实际上只由一个对象－－全局对象－－组成。全局执行环境也会有变量实例化的过程，它的内部函数就是涉及大部分 JavaScript 代码的、常规的顶级函数声明。而且，在变量实例化过程中全局对象就是可变对象，这就是为什么全局性声明的函数是全局对象属性的原因。全局性声明的变量同样如此。 </P>
<P>全局执行环境也会使用 <CODE>this</CODE> 对象来引用全局对象。 </P>
</H3><H3><A [[scope]]&gt;</A></H3>
</A><P>调用函数时创建的执行环境会包含一个作用域链，这个作用域链是通过将该执行环境的活动（可变）对象添加到保存于所调用函数对象的 <CODE>[[scope]]</CODE> 属性中的作用域链前端而构成的。所以，理解函数对象内部的 <CODE>[[scope]]</CODE> 属性的定义过程至关重要。 </P>
<P>在 ECMAScript 中，函数也是对象。函数对象在变量实例化过程中会根据函数声明来创建，或者是在计算函数表达式或调用 <CODE>Function</CODE> 构造函数时创建。 </P>
<P>通过调用 <CODE>Function</CODE> 构造函数创建的函数对象，其内部的 <CODE>[[scope]]</CODE> 属性引用的作用域链中始终只包含全局对象。 </P>
<P>通过函数声明或函数表达式创建的函数对象，其内部的 <CODE>[[scope]]</CODE> 属性引用的则是创建它们的执行环境的作用域链。 </P>
<P>在最简单的情况下，比如声明如下全局函数：- </P><PRE>function exampleFunction(formalParameter){
    ...   <SPAN 函数体内的代码></SPAN>
}
</PRE>
<P>当为创建全局执行环境而进行变量实例化时，会根据上面的函数声明创建相应的函数对象。因为全局执行环境的作用域链中只包含全局对象，所以它就给自己创建的、并以名为“exampleFunction”的属性引用的这个函数对象的内部 <CODE>[[scope]]</CODE> 属性，赋予了只包含全局对象的作用域链。 </P>
<P>当在全局环境中计算函数表达式时，也会发生类似的指定作用域链的过程：- </P><PRE>var exampleFuncRef = function(){
    ...   <SPAN 函数体代码></SPAN>
}
</PRE>
<P>在这种情况下，不同的是在全局执行环境的变量实例化过程中，会先为全局对象创建一个命名属性。而在计算赋值语句之前，暂时不会创建函数对象，也不会将该函数对象的引用指定给全局对象的命名属性。但是，最终还是会在全局执行环境中创建这个函数对象（当计算函数表达式时。译者注），而为这个创建的函数对象的 <CODE>[[scope]]</CODE> 属性指定的作用域链中仍然只包含全局对象。 </P>
<P>内部的函数声明或表达式会导致在包含它们的外部函数的执行环境中创建相应的函数对象，因此这些函数对象的作用域链会稍微复杂一些。在下面的代码中，先定义了一个带有内部函数声明的外部函数，然后调用外部函数： </P><PRE>function exampleOuterFunction(formalParameter){
    function exampleInnerFuncitonDec(){
        ... <SPAN 内部函数体代码></SPAN>
    }
    ...  <SPAN 其余的外部函数体代码></SPAN>
}

exampleOuterFunction( 5 );
</PRE>
<P>与外部函数声明对应的函数对象会在全局执行环境的变量实例化过程中被创建。因此，外部函数对象的 <CODE>[[scope]]</CODE> 属性中会包含一个只有全局对象的“单项目”作用域链。 </P>
<P>当在全局执行环境中调用 <CODE>exampleOuterFunction</CODE> 函数时，会为该函数调用创建一个新的执行环境和一个活动（可变）对象。这个新执行环境的作用域就由新的活动对象后跟外部函数对象的 <CODE>[[scope]]</CODE> 属性所引用的作用域链（只有全局对象）构成。在新执行环境的变量实例化过程中，会创建一个与内部函数声明对应的函数对象，而同时会给这个函数对象的 <CODE>[[scope]]</CODE> 属性指定创建该函数对象的执行环境（即新执行环境。译者注）的作用域值－－即一个包含活动对象后跟全局对象的作用域链。 </P>
<P>到目前为止，所有过程都是自动、或者由源代码的结构所控制的。但我们发现，执行环境的作用域链定义了执行环境所创建的函数对象的 <CODE>[[scope]]</CODE> 属性，而函数对象的 <CODE>[[scope]]</CODE> 属性则定义了它的执行环境的作用域（包括相应的活动对象）。不过，ECMAScript 也提供了用于修改作用域链 <CODE>with</CODE> 语句。 </P>
<P><CODE>with</CODE> 语句会计算一个表达式，如果该表达式是一个对象，那么就将这个对象添加到当前执行环境的作用域链中（在活动&lt;可变&gt;对象之前）。然后，执行 <CODE>with</CODE> 语句（它自身也可能是一个语句块）中的其他语句。之后，又恢复到调用它之前的执行环境的作用域链中。 </P>
<P><CODE>with</CODE> 语句不会影响在变量实例化过程中根据函数声明创建函数对象。但是，可以在一个 <CODE>with</CODE> 语句内部对函数表达式求值：- </P><PRE><SPAN 创建全局变量 - y - 它引用一个对象：- */></SPAN>
var y = {x:5}; <SPAN 带有一个属性 - x - 的对象直接量></SPAN>
function exampleFuncWith(){
    var z;
    <SPAN 将全局对象 - y - 引用的对象添加到作用域链的前端：- */></SPAN>
    with(y){
        <SPAN 对函数表达式求值，以创建函数对象并将该函数对象的引用指定给局部变量 - z - :-  */></SPAN>
        z = function(){
            ... <SPAN 内部函数表达式中的代码;></SPAN>
        }
    }
    ... 
}

<SPAN 执行 - exampleFuncWith - 函数:- */></SPAN>
exampleFuncWith();
</PRE>
<P>在调用 <CODE>exampleFuncWith</CODE> 函数所创建的执行环境中包含一个由其活动对象后跟全局对象构成的作用域链。而在执行 <CODE>with</CODE> 语句时，又会把全局变量 <CODE>y</CODE> 引用的对象添加到这个作用域链的前端。在对其中的函数表达式求值的过程中，所创建函数对象的 <CODE>[[scope]]</CODE> 属性与创建它的执行环境的作用域保持一致－－即，该属性会引用一个由对象 <CODE>y</CODE> 后跟调用外部函数时所创建执行环境的活动对象，后跟全局对象的作用域链。 </P>
<P>当与 <CODE>with</CODE> 语句相关的语句块执行结束时，执行环境的作用域得以恢复（<CODE>y</CODE> 会被移除），但是已经创建的函数对象（<CODE>z</CODE>。译者注）的 <CODE>[[scope]]</CODE> 属性所引用的作用域链中位于最前面的仍然是对象 <CODE>y</CODE>。 </P>
</H2><H3><A   ></A><P>标识符是沿作用域链逆向解析的。ECMA 262 将 <CODE>this</CODE> 归类为关键字而不是标识符，并非不合理。因为解析 <CODE>this</CODE> 值时始终要根据使用它的执行环境来判断，而与作用域链无关。 </P>
<P>标识符解析从作用域链中的第一个对象开始。检查该对象中是否包含与标识符对应的属性名。因为作用域链是一条对象链，所以这个检查过程也会包含相应对象的原型链（如果有）。如果没有在作用域链的第一个对象中发现相应的值，解析过程会继续搜索下一个对象。这样依次类推直至找到作用域链中包含以标识符为属性名的对象为止，也有可能在作用域链的所有对象中都没有发现该标识符。 </P>
<P>当基于对象使用属性访问器时，也会发生与上面相同的标识符解析过程。当属性访问器中有相应的属性可以替换某个对象时，这个属性就成为表示该对象的标识符，该对象在作用域链中的位置进而被确定。全局对象始终都位于作用域链的尾端。 </P>
<P>因为与函数调用相关的执行环境将会把活动（可变）对象添加到作用域链的前端，所以在函数体内使用的标识符会首先检查自己是否与形式参数、内部函数声明的名称或局部变量一致。这些都可以由活动（可变）对象的命名属性来确定。 </P>
</H3><H2><A   ><H3><A   ></A><P>ECMAScript 要求使用自动垃圾收集机制。但规范中并没有详细说明相关的细节，而是留给了实现来决定。但据了解，相当一部分实现对它们的垃圾收集操作只赋予了很低的优先级。但是，大致的思想都是相同的，即如果对象不再“可引用（由于不存在对它的引用，使执行代码无法再访问到它）”时，该对象就成为垃圾收集的目标。因而，在将来的某个时刻会将这个对象销毁并将它所占用的一切资源释放，以便操作系统重新利用。 </P>
<P>正常情况下，当退出一个执行环境时就会满足类似的条件。此时，作用域链结构中的活动（可变）对象以及在该执行环境中创建的任何对象－－包括函数对象，都不再“可引用”，因此将成为垃圾收集的目标。 </P>
</H3><H3><A   ></A><P>闭包是通过在对一个函数调用的执行环境中返回一个函数对象构成的。比如，在对函数调用的过程中，将一个对内部函数对象的引用指定给另一个对象的属性。或者，直接将这样一个（内部）函数对象的引用指定给一个全局变量、或者一个全局性对象的属性，或者一个作为参数以引用方式传递给外部函数的对象。例如：- </P><PRE>function exampleClosureForm(arg1, arg2){
    var localVar = 8;
    function exampleReturned(innerArg){
        return ((arg1 + arg2)/(innerArg + localVar));
    }
    <SPAN 返回一个定义为 exampleReturned 的内部函数的引用 -:-  */></SPAN>
    return exampleReturned;
}

var globalVar = exampleClosureForm(2, 4);
</PRE>
<P>这种情况下，在调用外部函数 <CODE>exampleClosureForm</CODE> 的执行环境中所创建的函数对象就不会被当作垃圾收集，因为该函数对象被一个全局变量所引用，而且仍然是可以访问的，甚至可以通过 <CODE>globalVar(n)</CODE> 来执行。 </P>
<P>的确，情况比正常的时候要复杂一些。因为现在这个被变量 <CODE>globalVar</CODE> 引用的内部函数对象的 <CODE>[[scope]]</CODE> 属性所引用的作用域链中，包含着属于创建该内部函数对象的执行环境的活动对象（和全局对象）。由于在执行被 <CODE>globalVar</CODE> 引用的函数对象时，每次都要把该函数对象的 <CODE>[[scope]]</CODE> 属性所引用的整个作用域链添加到创建的（内部函数的）执行环境的作用域中（即此时的作用域中包括：内部执行环境的活动对象、外部执行环境的活动对象、全局对象。译者注）， 所以这个（外部执行环境的）活动对象不会被当作垃圾收集。 </P>
<P>闭包因此而构成。此时，内部函数对象拥有自由的变量，而位于该函数作用域链中的活动（可变）对象则成为与变量绑定的环境。 </P>
<P>由于活动（可变）对象受限于内部函数对象（现在被 <CODE>globalVar</CODE> 变量引用）的 <CODE>[[scope]]</CODE> 属性中作用域链的引用，所以活动对象连同它的变量声明－－即属性的值，都会被保留。而在对内部函数调用的执行环境中进行作用域解析时，将会把与活动（可变）对象的命名属性一致的标识符作为该对象的属性来解析。活动对象的这些属性值即使是在创建它的执行环境退出后，仍然可以被读取和设置。 </P>
<P>在上面的例子中，当外部函数返回（退出它的执行环境）时，其活动（可变）对象的变量声明中记录了形式参数、内部函数定义以及局部变量的值。<CODE>arg1</CODE> 属性的值为 <CODE>2</CODE>，而 <CODE>arg2</CODE> 属性的值为 <CODE>4</CODE>，<CODE>localVar</CODE> 的值是 <CODE>8</CODE>，还有一个 <CODE>exampleReturned</CODE> 属性，它引用由外部函数返回的内部函数对象。（为方便起见，我们将在后面的讨论中，称这个活动&lt;可变&gt;对象为 "ActOuter1"）。 </P>
<P>如果再次调用 <CODE>exampleClosureForm</CODE> 函数，如：- </P><PRE>var secondGlobalVar = exampleClosureForm(12, 3);
</PRE>
<P>- 则会创建一个新的执行环境和一个新的活动对象。而且，会返回一个新的函数对象，该函数对象的 <CODE>[[scope]]</CODE> 属性引用的作用域链与前一次不同，因为这一次的作用域链中包含着第二个执行环境的活动对象，而这个活动对象的属性 <CODE>arg1</CODE> 值为 <CODE>12</CODE> 而属性 <CODE>arg2</CODE> 值为 <CODE>3</CODE>。（为方便起见，我们将在后面的讨论中，称这个活动&lt;可变&gt;对象为 "ActOuter2"）。 </P>
<P>通过第二次执行 <CODE>exampleClosureForm</CODE> 函数，第二个、也是截然不同的闭包诞生了。 </P>
<P>通过执行 <CODE>exampleClosureForm</CODE> 创建的两个函数对象分别被指定给了全局变量 <CODE>globalVar</CODE> 和 <CODE>secondGlobalVar</CODE>，并返回了表达式 <CODE>((arg1 + arg2)/(innerArg + localVar))</CODE>。该表达式对其中的四个标识符应用了不同的操作符。如何确定这些标识符的值是体现闭包价值的关键所在。 </P>
<P>我们来看一看，在执行由 <CODE>globalVar</CODE> 引用的函数对象－－如 <CODE>globalVar(2)</CODE>－－时的情形。此时，会创建一个新的执行环境和相应的活动对象（我们将称之为“ActInner1”），并把该活动对象添加到执行的函数对象的 <CODE>[[scope]]</CODE> 属性所引用的作用域链的前端。ActInner1 会带有一个属性 <CODE>innerArg</CODE>，根据传递的形式参数，其值被指定为 <CODE>2</CODE>。这个新执行环境的作用域链变成： <SPAN ></SPAN></P>
<P>为了返回表达式 <CODE>((arg1 + arg2)/(innerArg + localVar))</CODE> 的值，要沿着作用域链进行标识符解析。表达式中标识符的值将通过依次查找作用域链中每个对象（与标识符名称一致）的属性来确定。 </P>
<P>作用域链中的第一个对象是 ActInner1，它有一个名为 <CODE>innerArg</CODE> 的属性，值是 <CODE>2</CODE>。所有其他三个标识符在 ActOuter1 中都有对应的属性：<CODE>arg1</CODE> 是 <CODE>2</CODE>，<CODE>arg2</CODE> 是 <CODE>4</CODE> 而 <CODE>localVar</CODE> 是 <CODE>8</CODE>。最后，函数调用返回 <CODE>((2 + 2)/(2 + 8))</CODE>。 </P>
<P>现在再来看一看由 <CODE>secondGlobalVar</CODE> 引用的同一个函数对象的执行情况，比如 <CODE>secondGlobalVar(5)</CODE>。我们把这次创建的新执行环境的活动对象称为 “ActInner2”，相应的作用域链就变成了：<SPAN 返回 ><CODE>innerArg</CODE> 的值 <CODE>5</CODE>，而 ActOuter2 分别返回 <CODE>arg1</CODE>、<CODE>arg2</CODE> 和 <CODE>localVar</CODE> 的值 <CODE>12</CODE>、<CODE>3</CODE> 和 <CODE>8</CODE>。函数调用返回的值就是 <CODE>((12 + 3)/(5 + 8))</CODE>。 </SPAN></P>
<P>如果再执行一次 <CODE>secondGlobalVar</CODE>，则又会有一个新活动对象被添加到作用域链的前端，但 ActOuter2 仍然是链中的第二个对象，而他的命名属性会再次用于完成标识符 <CODE>arg1</CODE>、<CODE>arg2</CODE> 和 <CODE>localVar</CODE> 的解析。 </P>
<P>这就是 ECMAScript 的内部函数获取、维持和访问创建他们的执行环境的形式参数、声明的内部函数以及局部变量的过程。这个过程说明了构成闭包以后，内部的函数对象在其存续过程中，如何维持对这些值的引用、如何对这些值进行读取的机制。即，创建内部函数对象的执行环境的活动（可变）对象，会保留在该函数对象的 <CODE>[[scope]]</CODE> 属性所引用的作用域链中。直到所有对这个内部函数的引用被释放，这个函数对象才会成为垃圾收集的目标（连同它的作用域链中任何不再需要的对象）。 </P>
<P>内部函数自身也可能有内部函数。在通过函数执行返回内部函数构成闭包以后，相应的闭包自身也可能会返回内部函数从而构成它们自己的闭包。每次作用域链嵌套，都会增加由创建内部函数对象的执行环境引发的新活动对象。ECMAScript 规范要求作用域链是临时性的，但对作用域链的长度却没有加以限制。在具体实现中，可能会存在实际的限制，但还没有发现有具体限制数量的报告。目前来看，嵌套的内部函数所拥有的潜能，仍然超出了使用它们的人的想像能力。 </P>
</H3><H2><A   ></A><P>对这个问题的回答可能会令你惊讶－－闭包什么都可以做。据我所知，闭包使得 ECMAScript 能够模仿任何事物，因此局限性在于设计和实现要模仿事物的能力。只是从字面上看可能会觉得这么说很深奥，下面我们就来看一些更有实际意义的例子。 </P>
</H2><H3><A 1：为函数引用设置延时></A></H3>
</A><P>闭包的一个常见用法是在执行函数之前为要执行的函数提供参数。例如：将函数作为 <CODE>setTimout</CODE> 函数的第一个参数，这在 Web 浏览器的环境下是非常常见的一种应用。 </P>
<P><CODE>setTimeout</CODE> 用于有计划地执行一个函数（或者一串 JavaScript 代码，不是在本例中），要执行的函数是其第一个参数，其第二个参数是以毫秒表示的执行间隔。也就是说，当在一段代码中使用 <CODE>setTimeout</CODE> 时，要将一个函数的引用作为它的第一个参数，而将以毫秒表示的时间值作为第二个参数。但是，传递函数引用的同时无法为计划执行的函数提供参数。 </P>
<P>然而，可以在代码中调用另外一个函数，由它返回一个对内部函数的引用，再把这个对内部函数对象的引用传递给 <CODE>setTimeout</CODE> 函数。执行这个内部函数时要使用的参数在调用返回它的外部函数时传递。这样，<CODE>setTimeout</CODE> 在执行这个内部函数时，不用传递参数，但该内部函数仍然能够访问在调用返回它的外部函数时传递的参数： </P><PRE>function callLater(paramA, paramB, paramC){
    <SPAN 返回一个由函数表达式创建的匿名内部函数的引用:- */  ></SPAN>
    return (function(){
        <SPAN 这个内部函数将通过 - setTimeout - 执行，           而且当它执行时它会读取并按照传递给           外部函数的参数行事：          */></SPAN>
        paramA[paramB] = paramC;
    });
}

...

<SPAN 调用这个函数将返回一个在其执行环境中创建的内部函数对象的引用。   传递的参数最终将作为外部函数的参数被内部函数使用。   返回的对内部函数的引用被赋给一个全局变量:-  */  ></SPAN>
var functRef = callLater(elStyle, "display", "none");
<SPAN 调用 setTimeout 函数，将赋给变量 - functRef -   的内部函数的引用作为传递的第一个参数:- */   ></SPAN>
hideMenu=setTimeout(functRef, 500);
</PRE>
</H2><H3><A 2: 通过对象实例方法关联函数></A></H3><A href="http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.html#">回到顶部</A> 
<P>许多时候我们需要将一个函数对象暂时挂到一个引用上留待后面执行，因为不等到执行的时候是很难知道其具体参数的，而先前将它赋给那个引用的时候更是压根不知道的。 （此段由 <A href="http://blog.csdn.net/pongba">pangba 刘未鹏</A> 翻译） </P>
<P>（luyy朋友的翻译_2008-7-7更新）很多时候需要将一个函数引用进行赋值，以便在将来某个时候执行该函数，在执行这些函数时给函数提供参数将会是有用处的，但这些参数在执行时不容易获得，他们只有在上面赋值给时才能确定。 </P>
<P are many other circumstances when a reference to a function object is assigned so that it would be executed at some future time where it is useful to provide parameters for the execution of that function that would not be easily available at the time of execution but cannot be known until the moment of assignment.）></P>
<P>一个相关的例子是，用 JavaScript 对象来封装与特定 DOM 元素的交互。这个 JavaScript 对象具有 <CODE>doOnClick</CODE>、<CODE>doMouseOver</CODE> 和 <CODE>doMouseOut</CODE> 方法，并且当用户在该特定的 DOM 元素中触发了相应的事件时要执行这些方法。不过，可能会创建与不同的 DOM 元素关联的任意数量的 JavaScript 对象，而且每个对象实例并不知道实例化它们的代码将会如何操纵它们（即注册事件处理函数与定义相应的事件处理函数分离。译者注）。这些对象实例并不知道如何在全局环境中引用它们自身，因为它们不知道将会指定哪个全局变量（如果有）引用它们的实例。 </P>
<P>因而问题可以归结为执行一个与特定的 JavaScript 对象关联的事件处理函数，并且要知道调用该对象的哪个方法。</P>
<P>下面这个例子使用了一个基于闭包构建的一般化的函数（此句多谢未鹏指点），该函数会将对象实例与 DOM 元素事件关联起来，安排执行事件处理程序时调用对象实例的指定方法，给象的指定方法传递的参数是事件对象和与元素关联的引用，该函数返回执行相应方法后的返回值。 </P><PRE><SPAN 一个关联对象实例和事件处理器的函数。   它返回的内部函数被用作事件处理器。对象实例以 - obj - 参数表示，   而在该对象实例中调用的方法名则以 - methodName - （字符串）参数表示。   */   ></SPAN>
function associateObjWithEvent(obj, methodName){
    <SPAN 下面这个返回的内部函数将作为一个 DOM 元素的事件处理器*/   ></SPAN>
    return (function(e){
        <SPAN    ></SPAN>
        e = e||window.event;
        <SPAN 事件处理器通过保存在字符串 - methodName - 中的方法名调用了对象         - obj - 的一个方法。并传递已经规范化的事件对象和触发事件处理器的元素         的引用 - this - （之所以 this 有效是因为这个内部函数是作为该元素的方法执行的）        */   ></SPAN>
        return obj[methodName](e, this);
    });
}

<SPAN 这个构造函数用于创建将自身与 DOM 元素关联的对象，      DOM 元素的 ID 作为构造函数的字符串参数。      所创建的对象会在相应的元素触发 onclick、      onmouseover 或 onmouseout 事件时，      调用相应的方法。   */   ></SPAN>
function DhtmlObject(elementId){
    <SPAN 调用一个返回 DOM 元素（如果没找到返回 null）引用的函数，      必需的参数是 ID。 将返回的值赋给局部变量 - el -。       */ ></SPAN>
    var el = getElementWithId(elementId);
    <SPAN ></SPAN>
    if(el){
        <SPAN 为给元素的事件处理器指定一个函数，该对象调用了        - associateObjWithEvent - 函数。        同时对象将自身（通过 - this - 关键字）作为调用方法的对象，        并提供了调用的方法名称。 - associateObjWithEvent - 函数会返回        一个内部函数，该内部函数被指定为 DOM 元素的事件处理器。        在响应事件时，执行这个内部函数就会调用必要的方法。        */></SPAN>
        el.onclick = associateObjWithEvent(this, "doOnClick");
        el.onmouseover = associateObjWithEvent(this, "doMouseOver");
        el.onmouseout = associateObjWithEvent(this, "doMouseOut");
        ...
    }
}
DhtmlObject.prototype.doOnClick = function(event, element){
    ... <SPAN doOnClick 方法体。></SPAN>.
}
DhtmlObject.prototype.doMouseOver = function(event, element){
    ... <SPAN doMouseOver 方法体。></SPAN>
}
DhtmlObject.prototype.doMouseOut = function(event, element){
    ... <SPAN doMouseOut 方法体。></SPAN>
}
</PRE>
<P>这样，<CODE>DhtmlObject</CODE> 的任何实例都会将自身与相应的 DOM 元素关联起来，而这些 DOM 元素不必知道其他代码如何操纵它们（即当触发相应事件时，会执行什么代码。译者注），也不必理会全局命名空间的影响以及与 <CODE>DhtmlObject</CODE> 的其他实例间存在冲突的危险。 </P>
<H3><A 3：包装相关的功能></A></H3>
<P>闭包可以用于创建额外的作用域，通过该作用域可以将相关的和具有依赖性的代码组织起来，以便将意外交互的风险降到最低。假设有一个用于构建字符串的函数，为了避免重复性的连接操作（和创建众多的中间字符串），我们的愿望是使用一个数组按顺序来存储字符串的各个部分，然后再使用 <CODE>Array.prototype.join</CODE> 方法（以空字符串作为其参数）输出结果。这个数组将作为输出的缓冲器，但是将数组作为函数的局部变量又会导致在每次调用函数时都重新创建一个新数组，这在每次调用函数时只重新指定数组中的可变内容的情况下并不是必要的。 </P>
<P>一种解决方案是将这个数组声明为全局变量，这样就可以重用这个数组，而不必每次都建立新数组。但这个方案的结果是，除了引用函数的全局变量会使用这个缓冲数组外，还会多出一个全局属性引用数组自身。如此不仅使代码变得不容易管理，而且，如果要在其他地方使用这个数组时，开发者必须要再次定义函数和数组。这样一来，也使得代码不容易与其他代码整合，因为此时不仅要保证所使用的函数名在全局命名空间中是唯一的，而且还要保证函数所依赖的数组在全局命名空间中也必须是唯一的。 </P>
<P>而通过闭包可以使作为缓冲器的数组与依赖它的函数关联起来（优雅地打包），同时也能够维持在全局命名空间外指定的缓冲数组的属性名，免除了名称冲突和意外交互的危险。 </P>
<P>其中的关键技巧在于通过执行一个单行（in-line）函数表达式创建一个额外的执行环境，而将该函数表达式返回的内部函数作为在外部代码中使用的函数。此时，缓冲数组被定义为函数表达式的一个局部变量。这个函数表达式只需执行一次，而数组也只需创建一次，就可以供依赖它的函数重复使用。 </P>
<P>下面的代码定义了一个函数，这个函数用于返回一个 <SPAN title="HyperText Mark-up Language"><ABBR title="HyperText Mark-up Language">HTML</ABBR></SPAN> 字符串，其中大部分内容都是常量，但这些常量字符序列中需要穿插一些可变的信息，而可变的信息由调用函数时传递的参数提供。 </P>
<P>通过执行单行函数表达式返回一个内部函数，并将返回的函数赋给一个全局变量，因此这个函数也可以称为全局函数。而缓冲数组被定义为外部函数表达式的一个局部变量。它不会暴露在全局命名空间中，而且无论什么时候调用依赖它的函数都不需要重新创建这个数组。 </P><PRE><SPAN 声明一个全局变量 - getImgInPositionedDivHtml -   并将一次调用一个外部函数表达式返回的内部函数赋给它。       这个内部函数会返回一个用于表示绝对定位的 DIV 元素     包围着一个 IMG 元素 的 ><SPAN title="HyperText Mark-up Language"><ABBR title="HyperText Mark-up Language">HTML</ABBR></SPAN> 字符串，这样一来，
   所有可变的属性值都由调用该函数时的参数提供：
*/</SPAN>
var getImgInPositionedDivHtml = (function(){
     [ http://img.bimg.126.net/photo/oeVtR29iQQ_AJmg6PlXx-w==/1424263382157276883.jpg+ZG+JLS+KPB+ZYB+ ] </SPAN>
    var buffAr = [
        '&lt;div id="',
        '',   <SPAN 1, DIV ID 属性></SPAN>
        '" style="position:absolute;top:',
        '',   <SPAN 3, DIV 顶部位置></SPAN>
        'px;left:',
        '',   <SPAN 5, DIV 左端位置></SPAN>
        'px;width:',
        '',   <SPAN 7, DIV 宽度></SPAN>
        'px;height:',
        '',   <SPAN 9, DIV 高度></SPAN>
        'px;overflow:hidden;\"&gt;&lt;img src=\"',
        '',   <SPAN 11, IMG URL></SPAN>
        '\" width=\"',
        '',   <SPAN 13, IMG 宽度></SPAN>
        '\" height=\"',
        '',   <SPAN 15, IMG 调蓄></SPAN>
        '\" alt=\"',
        '',   <SPAN 17, IMG alt 文本内容></SPAN>
        '\"&gt;&lt;\/div&gt;'
    ];
    <SPAN 返回作为对函数表达式求值后结果的内部函数对象。   这个内部函数就是每次调用执行的函数   - getImgInPositionedDivHtml( ... ) -      */></SPAN>
    return (function(url, id, width, height, top, left, altText){
        <SPAN 将不同的参数插入到缓冲数组相应的位置：          */></SPAN>
        buffAr[1] = id;
        buffAr[3] = top;
        buffAr[5] = left;
        buffAr[13] = (buffAr[7] = width);
        buffAr[15] = (buffAr[9] = height);
        buffAr[11] = url;
        buffAr[17] = altText;
        <SPAN 返回通过使用空字符串（相当于将数组元素连接起来）    连接数组每个元素后形成的字符串：          */></SPAN>
        return buffAr.join('');
    }); <SPAN   })();  ><SPAN :单行外部函数表达式。*/></SPAN>
</PRE>
<P>如果一个函数依赖于另一（或多）个其他函数，而其他函数又没有必要被其他代码直接调用，那么可以运用相同的技术来包装这些函数，而通过一个公开暴露的函数来调用它们。这样，就将一个复杂的多函数处理过程封装成了一个具有移植性的代码单元。 </P>
<H3><A   ></A><P>有关闭包的一个可能是最广为人知的应用是 <A href="http://www.crockford.com/javascript/private.html">Douglas Crockford's technique for the emulation of private instance variables in ECMAScript objects</A>。这种应用方式可以扩展到各种嵌套包含的可访问性（或可见性）的作用域结构，包括 <A href="http://www.litotes.demon.co.uk/js_info/private_static.html">the emulation of private static members for ECMAScript objects</A>。 </P>
<P>闭包可能的用途是无限的，可能理解其工作原理才是把握如何使用它的最好指南。 </P>
</H3><H2><A   ></A><P>在创建可访问的内部函数的函数体之外解析该内部函数就会构成闭包。这表明闭包很容易创建，但这样一来可能会导致一种结果，即没有认识到闭包是一种语言特性的 JavaScript 作者，会按照内部函数能完成多种任务的想法来使用内部函数。但他们对使用内部函数的结果并不明了，而且根本意识不到创建了闭包，或者那样做意味着什么。 </P>
<P>正如下一节谈到 IE 中内存泄漏问题时所提及的，意外创建的闭包可能导致严重的负面效应，而且也会影响到代码的性能。问题不在于闭包本身，如果能够真正做到谨慎地使用它们，反而会有助于创建高效的代码。换句话说，使用内部函数会影响到效率。 </P>
<P>使用内部函数最常见的一种情况就是将其作为 DOM 元素的事件处理器。例如，下面的代码用于向一个链接元素添加 onclick 事件处理器： </P><PRE><SPAN 定义一个全局变量，通过下面的函数将它的值     作为查询字符串的一部分添加到链接的 - href - 中：  */></SPAN>
var quantaty = 5;
<SPAN 当给这个函数传递一个链接（作为函数中的参数 - linkRef -）时，     会将一个 onclick 事件处理器指定给该链接，该事件处理器     将全局变量 - quantaty - 的值作为字符串添加到链接的 - href -      属性中，然后返回 true 使该链接在单击后定位到由  - href -      属性包含的查询字符串指定的资源：  */></SPAN>
function addGlobalQueryOnClick(linkRef){
    <SPAN 如果可以将参数 - linkRef - 通过类型转换为 ture        （说明它引用了一个对象）：      */></SPAN>
    if(linkRef){
        <SPAN 对一个函数表达式求值，并将对该函数对象的引用             指定给这个链接元素的 onclick 事件处理器：          */></SPAN>
        linkRef.onclick = function(){
            <SPAN 这个内部函数表达式将查询字符串                 添加到附加事件处理器的元素的 - href - 属性中：              */></SPAN>
            this.href += ('?quantaty='+escape(quantaty));
            return true;
        };
    }
}
</PRE>
<P>无论什么时候调用 <CODE>addGlobalQueryOnClick</CODE> 函数，都会创建一个新的内部函数（通过赋值构成了闭包）。从效率的角度上看，如果只是调用一两次 <CODE>addGlobalQueryOnClick</CODE> 函数并没有什么大的妨碍，但如果频繁使用该函数，就会导致创建许多截然不同的函数对象（每对内部函数表达式求一次值，就会产生一个新的函数对象）。 </P>
<P>上面例子中的代码没有关注内部函数在创建它的函数外部可以访问（或者说构成了闭包）这一事实。实际上，同样的效果可以通过另一种方式来完成。即单独地定义一个用于事件处理器的函数，然后将该函数的引用指定给元素的事件处理属性。这样，只需创建一个函数对象，而所有使用相同事件处理器的元素都可以共享对这个函数的引用： </P><PRE><SPAN 定义一个全局变量，通过下面的函数将它的值     作为查询字符串的一部分添加到链接的 - href - 中：  */></SPAN>
var quantaty = 5;

<SPAN 当把一个链接（作为函数中的参数 - linkRef -）传递给这个函数时，     会给这个链接添加一个 onclick 事件处理器，该事件处理器会     将全局变量  - quantaty - 的值作为查询字符串的一部分添加到     链接的 - href -  中，然后返回 true，以便单击链接时定位到由     作为 - href - 属性值的查询字符串所指定的资源：  */></SPAN>
function addGlobalQueryOnClick(linkRef){
    <SPAN 如果 - linkRef - 参数能够通过类型转换为 true      （说明它引用了一个对象）：      */></SPAN>
    if(linkRef){
        <SPAN 将一个对全局函数的引用指定给这个链接             的事件处理属性，使函数成为链接元素的事件处理器：          */></SPAN>
        linkRef.onclick = forAddQueryOnClick;
    }
}
<SPAN 声明一个全局函数，作为链接元素的事件处理器，     这个函数将一个全局变量的值作为要添加事件处理器的     链接元素的  - href - 值的一部分：  */></SPAN>
function forAddQueryOnClick(){
    this.href += ('?quantaty='+escape(quantaty));
    return true;
}
</PRE>
<P>在上面例子的第一个版本中，内部函数并没有作为闭包发挥应有的作用。在那种情况下，反而是不使用闭包更有效率，因为不用重复创建许多本质上相同的函数对象。 </P>
<P>类似地考量同样适用于对象的构造函数。与下面代码中的构造函数框架类似的代码并不罕见： </P><PRE>function ExampleConst(param){
    <SPAN 通过对函数表达式求值创建对象的方法，         并将求值所得的函数对象的引用赋给要创建对象的属性：      */></SPAN>
    this.method1 = function(){
        ... <SPAN 方法体。></SPAN>
    };
    this.method2 = function(){
        ... <SPAN 方法体。></SPAN>
    };
    this.method3 = function(){
        ... <SPAN 方法体。></SPAN>
    };
    <SPAN 把构造函数的参数赋给对象的一个属性：      */></SPAN>
    this.publicProp = param;
}
</PRE>
<P>每当通过 <CODE>new ExampleConst(n)</CODE> 使用这个构造函数创建一个对象时，都会创建一组新的、作为对象方法的函数对象。因此，创建的对象实例越多，相应的函数对象也就越多。 </P>
<P>Douglas Crockford 提出的模仿 JavaScript 对象私有成员的技术，就利用了将对内部函数的引用指定给在构造函数中构造对象的公共属性而形成的闭包。如果对象的方法没有利用在构造函数中形成的闭包，那么在实例化每个对象时创建的多个函数对象，会使实例化过程变慢，而且将有更多的资源被占用，以满足创建更多函数对象的需要。 </P>
<P>这那种情况下，只创建一次函数对象，并把它们指定给构造函数 <CODE>prototype</CODE> 的相应属性显然更有效率。这样一来，它们就能被构造函数创建的所有对象共享了： </P><PRE>function ExampleConst(param){
    <SPAN 将构造函数的参数赋给对象的一个属性：      */></SPAN>
    this.publicProp = param;
}
<SPAN 通过对函数表达式求值，并将结果函数对象的引用     指定给构造函数原型的相应属性来创建对象的方法：  */></SPAN>
ExampleConst.prototype.method1 = function(){
    ... <SPAN 方法体。></SPAN>
};
ExampleConst.prototype.method2 = function(){
    ... <SPAN 方法体。></SPAN>
};
ExampleConst.prototype.method3 = function(){
    ... <SPAN 方法体。></SPAN>
};

</PRE>
</H2><H2><A Explorer 的内存泄漏问题 ></A></H2>
<P>Internet Explorer Web 浏览器（在 IE 4 到 IE 6 中核实）的垃圾收集系统中存在一个问题，即如果 ECMAScript 和某些宿主对象构成了 "循环引用"，那么这些对象将不会被当作垃圾收集。此时所谓的宿主对象指的是任何 DOM 节点（包括 document 对象及其后代元素）和 ActiveX 对象。如果在一个循环引用中包含了一或多个这样的对象，那么这些对象直到浏览器关闭都不会被释放，而它们所占用的内存同样在浏览器关闭之前都不会交回系统重用。 </P>
<P>当两个或多个对象以首尾相连的方式相互引用时，就构成了循环引用。比如对象 1 的一个属性引用了对象 2 ，对象 2 的一个属性引用了对象 3，而对象 3 的一个属性又引用了对象 1。对于纯粹的 ECMAScript 对象而言，只要没有其他对象引用对象 1、2、3，也就是说它们只是相互之间的引用，那么仍然会被垃圾收集系统识别并处理。但是，在 Internet Explorer 中，如果循环引用中的任何对象是 DOM 节点或者 ActiveX 对象，垃圾收集系统则不会发现它们之间的循环关系与系统中的其他对象是隔离的并释放它们。最终它们将被保留在内存中，直到浏览器关闭。 </P>
<P>闭包非常容易构成循环引用。如果一个构成闭包的函数对象被指定给，比如一个 DOM 节点的事件处理器，而对该节点的引用又被指定给函数对象作用域中的一个活动（或可变）对象，那么就存在一个循环引用。<SPAN -&gt;></SPAN><SPAN -&gt;></SPAN><SPAN -&gt;></SPAN><SPAN -&gt;></SPAN><SPAN ></SPAN></P>
<P>多加注意可以避免形成循环引用，而在无法避免时，也可以使用补偿的方法，比如使用 IE 的 onunload 事件来来清空（null）事件处理函数的引用。时刻意识到这个问题并理解闭包的工作机制是在 IE 中避免此类问题的关键。 </P></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200924104025828</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200924104025828</guid>
    <pubDate>Wed, 4 Mar 2009 22:40:25 +0800</pubDate>
    <dcterms:modified>2009-03-04T22:40:25+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[实例学习call、apply、callee用法]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200912613612865</link>
    <description><![CDATA[<div><div >
    <p>可能不少学习javascript在使用call,apply,callee时会感到困惑，以下希望对于你有所帮助：<br>
1、它是函数的方法或属性；<br>
2、它可以改变执行上下文的this指向；<br>
3、作为另一个对象调用一个方法(即可以把一个对象的方法作为另一个对象的方法来引用)；<br>
4、apply方法类似，但只能接收数组为参数；<br>
5、callee函数的调用者。</p>
<p>f.call(o,1,2) 等同于<br>
o.m = f;<br>
o.m(1,2);</p>
<p>例1：<br>
function o1(value){<br>
if(value &lt; 100){<br>
this.value = value;<br>
}else{<br>
this.value = 100;<br>
}<br>
}</p>
<p>function o2(value){<br>
o1.call(this,value);<br>
alert(this.value);<br>
}</p>
<p>var o = new o2(133554) //100&nbsp; 改变了this的指向</p>
<p>例2：<br>
function c1(){<br>
this.m1 = function(){<br>
alert(this.name);<br>
}<br>
}</p>
<p>function c2(){<br>
this.name = “mike”;<br>
}<br>
var nc1 = new c1();<br>
var nc2 = new c2(); //必须<br>
nc1.m1.call(nc2);&nbsp; //mike 把方法m1作为对象nc2的方法来引用</p>
<p>例3：<br>
<span> function o1(arg){<br>
if (arguments[1] &lt; 100) {<br>
this.value = </span><span>arguments[1] </span><span>;<br>
}<br>
else {<br>
this.value = 100;<br>
}<br>
}</span></p>
<p>function o2(arg){<br>
o1.apply(this, arg);<br>
alert(this.value);<br>
}</p>
<p>var o = new o2([101,60]) //60 参数只能是数组</p>
<p>callee用法，常用于匿名函数中<br>
var factorial = function(x){<br>
if(x &lt;= 1){<br>
return 1;<br>
}<br>
return x * arguments.callee(x - 1);<br>
}<br>
alert(factorial(5)); //120</p>
   </div></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200912613612865</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200912613612865</guid>
    <pubDate>Thu, 26 Feb 2009 13:36:12 +0800</pubDate>
    <dcterms:modified>2009-02-26T13:36:12+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[淘宝前端开发人员的心声]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200911892215217</link>
    <description><![CDATA[<div>转自淘宝前端开发某成员博客，与大家共勉。<br><h3>淘宝改版的喜与忧</h3>
<p>淘宝改版了，论坛上骂声一片。一天之内，长达<a target="_blank" href="http://forum.taobao.com/forum-14/show_thread----21029093-.htm">300多页的反馈</a>，的确让我们这些局内人很沮丧。我只说说“已买到/已卖出的宝贝”列表页面，从加入淘宝开始，就一直负责部分交易相关页面的前端工作，真的是很有感情了。</p>
<p>“已买到/已卖出的宝贝”页面，上次改版是08年6月份，回顾一下<a target="_blank" href="http://forum.taobao.com/forum-14/show_thread----16270357-0-.htm">当时的公告贴</a>吧。当时也有不少用户对新页面不满意，非常反对，要求恢复老版。和这次很多卖家的口号是一样的，只是这次反应更剧烈，有时想想，蛮戏剧化的（现在要求恢复的是当时极力反对的）。</p>
<p>关于网站改版，JavaEye的坛主robbin有过一篇很不错的<a target="_blank" href="http://www.javaeye.com/topic/141889">分析</a>。一般来说，改版要采取渐进式，一次不要发布太多功能，并且最好有个老旧并存，新版公测期。这两点，因为各种原因，淘宝这次明显没做好。但这和上层的决策有关，现在还难以看出好坏。改版的策略和方式，在此不多说（我这个小虾米也影响不了什么）。</p>
<p>我说一点能说的，以及我的担心：</p>
<p>首先，淘宝现在已然是个大象，很多新项目新功能都在开发中。淘宝鼓励做加法，同时大部分项目也只敢做加法。举个简单的例子，“已买到的宝贝”列表页
面，“我要秀”功能，很鸡肋的一个功能，而且里面的页面都好久没维护了，就是这样一个大部分用户不会去用的功能，却死活去不掉，因为这牵扯到麻烦，可能有
风险，于是一个项目一个项目下来，一直留到了现在。</p>
<p>这和我的理念有冲突，我推崇的是简单法则，我相信的是<a target="_blank" href="http://gettingreal.37signals.com/GR_chn.php">Getting Real</a>. 我觉得保持简单，突出核心竞争力，这也是淘宝应该做到的。小学，我们先学加法，然后才学减法，因为减法比加法更难。对于一个产品来说，减法更需要魄力。我亲爱的淘宝，什么时候，你才能学会做减法呢？（或许高层们比我看得更远更深，纯粹当我发牢骚吧。）</p>
<p>其次，淘宝已经是大象，大家都忙着新项目和新功能，对原有系统的一些问题，却不大愿意花费时间去改进。例子很明显，“我的淘宝”里面的页面，风格有
好几种，统一“我的淘宝”，这件事情两三年前就有人提，但一直到现在，却没有人真正的把这件事情做起来。都忙着做加法呢，没时间做扫地的工作了。真诚期望
淘宝什么时候能设立“默默无闻改进奖”，而不是仅搞个“轰轰烈烈创新奖”。（当然，我这里仅针对前端展示层。对于后台功能，比如这次改版，我相信对底层代
码是做了很多重构和改进工作的。但每次进入“我的淘宝”，心里忍不住还是会痛一下。）</p>
<p>最后，在淘宝开发流程中，还是有非常多的不足。这次改版发布后的调整过程中，视觉和交互设计师的精心设计，比不上高层的一句话。种种情况，职责的不分明，有时真让人怀疑，这是不是淘宝。（很多公司都有这种毛病，但身临其境，还是让人很郁闷。）</p><h3>对自己以及对公司的建议</h3>
<ol><li>加班要尊重员工自己的选择。如果的确需要加班，请选择合适的方式交流沟通。（我自己也做得不够好，性子有点急，以后一定要注意）</li><li>改版要慎重。一定要采取妥善的方式，尽早从最终用户中获取建议。</li><li>学学减法，我相信对淘宝有好处。</li><li>默默无闻的改进，有时比轰轰烈烈的创新更重要。</li><li>产品经理，项目经理，视觉设计师，交互设计师，要职责分明，要彼此尊重。</li><li>高层请在自己精通的领域指点江山，请不要轻易否定员工的努力，某些领域，你不一定比员工强，你的感觉也不一定对。</li></ol><h3>不加班冲突</h3>
<p>昨天因为不愿意加班，和一个项目经理Y发生了一些不愉快。Y的一部分理论是马云语录：“正常上班是正常的， 不正常上班也是正常的，
只有工作没有完成是不正常的。”
我坚持的是：“第一，在上班时间内，我肯定会努力解决问题，想尽一切办法。第二，如果上班时间内没搞定，对不起，家庭比工作更重要，我得先做更重要的事。
”</p>
<p>现在想想，Y的确有Y的难处，但这件事情，不应该通过强制加班来解决。在阿里，加班是自愿的，也是无酬的。当员工的确不想加班时，是应该可以自由选
择的。从加入淘宝一直到过年前，我几乎都是有求必应，有班必加。但人总有倦的时候，总有疲惫的时候，总有有想法的时候。我不想加班，Y却想通过加班来解决
问题，这个矛盾，我也不知道怎么解决。Y我理解你的难处，但也请你尊重我的选择。</p>
<p>马云的加班论，我一直觉得是谬论<span></span>，因为很难判定“一天应该完成哪些工作”。比如这个例子中，Y的理解是，今天要把反馈的
问题都改完。我的理解是，今天把工作时间内能做的事情做完。不同的角色，不同的角度，对“当天的工作是否完成”的判断是不同的，而且不存在对错。马云的不
少观点，都是初看有点道理，细想却经不起推敲。<br><br>作者：<span >lifesinger&nbsp; 原文链接：http://lifesinger.org/blog/?p=1346<br></span></p><br></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200911892215217</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200911892215217</guid>
    <pubDate>Wed, 18 Feb 2009 09:22:15 +0800</pubDate>
    <dcterms:modified>2009-02-18T09:22:15+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[页面性能改进-新闻首页改版]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/2475322009090721994</link>
    <description><![CDATA[<div><p>&nbsp;&nbsp; 在国内的门户网部中，页面多是追求大而全，而很少在页面性能上考虑；此次新闻改版，我们首次在页面性能上作了较大的改进力度，借助于yahoo开发的页面性能评测工具YSlow，得分截图如下：</p>
<p><a href="http://img.blog.163.com/photo/YAEqCcpSRyytc71u2lZWHg==/1453255304758282206.jpg" target="_blank"><img title="页面性能改进-新闻首页改版 - 罗金 - 用户体验" alt="页面性能改进-新闻首页改版 - 罗金 - 用户体验" src="http://img.blog.163.com/photo/YAEqCcpSRyytc71u2lZWHg==/1453255304758282206.jpg"></a><br>
总得分为80分：(A为最好，F为最差）<br>
第二点”Use a CDN”，采不采用CDN不是我们所能决定，这一点得分为0；<br>
第三点”Add an Expires header”，由于新闻首页里有财经的三个行情图，由于需要实时刷新，这三张图片是不能设置太长的过期时间，为此，这三个图导致扣了一半分；<br>
第九点”Reduce DNS lookups”，由于我们页面里的内容来源域名较多，有博客的、有有道的等，为此导致扣了一半分。其它的还算做的比较好了。<br>
&nbsp;&nbsp;&nbsp; 我们借助于第三方的软件测试，分数不是我们的最终目的，我们的目的是优化页面代码、提高用户的打开速度，用户的满意度才是我们的最终目的。其实在标签的语义化、Javascript代码还有改进的空间，这些都还需要我们整个团队的进一步努力。</p>
注：上线之后，由于广告代码的加入，分数降的很低。广告方面很需兄弟部门的努力和改进</div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/2475322009090721994</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/2475322009090721994</guid>
    <pubDate>Fri, 9 Jan 2009 12:07:21 +0800</pubDate>
    <dcterms:modified>2009-01-09T12:07:21+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[JavaScript的速度问题和未来 ]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200811312044397</link>
    <description><![CDATA[<div>转：http://www.openlab.net.cn/forums/threads/1385628.aspx<br><div >
                      <p>相对于Flex和SilverLigth，JavaScript的优势在于浏览器天然支持。我甚至觉得JavaScript可以作为启蒙性的编程语言，为什么呢？简单，方便。没有指针，没有复杂的语法，打开浏览器就能运行。对于任何初学抠代码的童鞋，真是太方便不过了。</p><p>JavaScript的问题也很突出，最受指责的，可能是它的执行速度。微软的IE浏览器里，JavaScript的速度是极其低下的，当然，在其他大多数主流浏览器里的速度，也很糟糕。</p><p>Google
Chrome浏览器的出现给JavaScript的速度带来了曙光，也打响了JavaScript性能大战。为什么说这个革命性的呢？因为Chrome浏
览器用了一种名叫
”V8“的JS执行引擎。原先所有的浏览器执行JavaScript，是采用”解释“的方法。相对于拥有自己相应虚拟机的
Flash（Flex），SilverLight，JavaFX/Applet，JavaScript的效率，差了一个数量级。</p><p>但是V8引
擎的出现，打破了”解释“模式。Chrome浏览器执行JavaScript，采用了和Java类似的方法：JIT（即时编译）。把JavaScript
优化编译成二进制本地执行文件并存放在内存里面。这种执行方法，使得JavaScript的速度在理论上能和Java/.NET一样快！相对传统的浏览
器，那是数量级的飞跃。</p><p>这样就出现了一种可能：我们可以开发更复杂的JavaScript应用，而不用求助于其他的前台技术。我们甚至可以用JavaScript来实现3D效果。</p><p>大家可以看看这个：</p><p><a href="http://www.xs4all.nl/%7Epeterned/3d/">http://www.xs4all.nl/~peterned/3d/</a></p><p>Chrome的V8引擎给大家带来了新的希望，紧接着，新的Safari浏览器也采用了更高效的JIT JavaScript 引擎，FireFox3.1亦不甘示弱，新一轮浏览器大战将打响。</p><p>上个月，微软承认JavaScript的速度在未来18个月内会有百倍提升，JavaScript的未来如何，我们拭目以待吧</p>
                      </div><br></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200811312044397</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200811312044397</guid>
    <pubDate>Wed, 3 Dec 2008 13:20:44 +0800</pubDate>
    <dcterms:modified>2008-12-03T13:20:44+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[香港印象]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200811212947157</link>
    <description><![CDATA[<div>&nbsp;&nbsp;&nbsp;&nbsp; 每去一个新地方，应该了解一下当地的风土人情，这次也不例外。<br>1、很羡慕香港的车：奔驰、宝马、凌志满街都是，大陆的车根本进不了这个市场，因为太烂了，只有看了香港的车，才知共产党有多黑；<br>2、香港的城市管理绝对是国内应该好好学习的，它们的街道虽然窄，但绝对是干净的，也并不是任何时候任何地方都有人在扫，要知道，那里的人力成本是比较高的，路边的电线杆，树木也见不到乱贴的小广告，那里一条街中有一块墙壁是专门让人乱贴的（估计是每条街都有）；<br>3、他们的房子很多是建在半山的，也是出名的贵，100平方米（它们用的是平方尺）的房子，稍微好点的就要1000万。这不是一般家庭可以承受的，所以大房子在香港人心目中是最大的梦想。<br>4、香港人很勤奋，很多头发已经白了不少的人仍然在辛勤的工作着，现在国内动不动就到了四十五就内退，或许是国内人太多了，但香港人口也不少啊。。。<br>5、香港色情MS是合法化的。。。<br><br>稍后传几张相片上来。。。<br><br></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200811212947157</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200811212947157</guid>
    <pubDate>Tue, 2 Dec 2008 13:29:47 +0800</pubDate>
    <dcterms:modified>2008-12-02T13:29:47+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[ 转变]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/247532200891011513677</link>
    <description><![CDATA[<div>不在限于工作相关的主题。<br><br>现在全世界都是谈论如何救市，股票不知跌到何时。<br><br>如果中国房地产崩溃，世界会如何？<br></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/247532200891011513677</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/247532200891011513677</guid>
    <pubDate>Fri, 10 Oct 2008 23:51:36 +0800</pubDate>
    <dcterms:modified>2008-10-10T23:51:36+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[产品]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/2475322008997637864</link>
    <description><![CDATA[<div><div >
    <p>关键字：生命周期 产品 创新 挖掘用户潜在的需求 细分用户 潜在竞争产品 用户体验</p>
<p>产品：互联网的各种应用都可以称为“狭义”上的产品，如搜索引擎、视频应用、门户网站、网络游戏等，再进一步细分，互联网中的一个互动策划活动都可
以称为一个产品。任何产品都有它的生命周期，必然会经历：萌芽、发展、繁荣、衰落、死亡，只是在不同的产品中，生命周期有长有短。</p>
<p>用户体验的最佳实践就是和产品开发的完美结合：包含创新、挖掘用户潜在的需求、细分用户、和潜在同类产品相比的优势。</p>
<p>创新永远是产品致胜的核心，其余三个是产品成功的重要条件，在进行产品开发之前，分析你的产品是否符合上述四个条件的一个或多个。</p>
<p>梦幻足球经理的PM在立项之前找我聊了一下，当时自己感觉这是一个不错的项目。但足球经理项目试运营了一个赛季后，数据结果却不是很理想，结合上面提到的四点去分析一下：<br>
1、足球经理不是一个创新的项目，国外已经有类似成功的产品；<br>
2、挖掘用户潜在的需求、细分用户，用户就是球迷，为球迷除了资讯之外多一个选择；<br>
3、和潜在同类产品相比，如FIFA系列的实战游戏，在娱乐操作方面明显处于下风；</p>
<p>另外足球经理项目自身有先天的不足之处：<br>
1、悬念失去过早：<br>
在漫长的赛季中，悬念失去过早。<br>
把游戏中人群分为三类：<br>
一、希望通过每轮累计积分获奖的人，此类用户如果是赛季进行二个月后才加入，最终基本会流失，因为28轮的总成绩和38轮的总成绩相比，明显处于下风，所以由于时间的先后顺序，导致悬念失去过早；<br>
二、对获不获奖无关紧要，纯粹是足球爱好者，只有这类用户才是最忠诚的；<br>
三、纯粹来玩玩，这类用户不容易留下，如上面提到的FIFA系列的实战游戏，操控性明显会强于足球经理。<br>
2、受客观赛程的影响：<br>
由于每一轮比赛场次有时会相隔几天，轮数之间的时间不固定，导致用户操作不便；</p>
<p>注：无意攻击足球经理项目，只是引出话题与大家探讨。</p>
   </div></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/2475322008997637864</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/2475322008997637864</guid>
    <pubDate>Thu, 9 Oct 2008 19:06:37 +0800</pubDate>
    <dcterms:modified>2008-10-09T19:06:37+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[回家]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/24753220089785835612</link>
    <description><![CDATA[<div>&nbsp; 国庆回了一趟乡下，调皮的侄儿依旧调皮。<br><a href="http://img.blog.163.com/photo/-URfdygq9adNqt4gPzxbnw==/2014234933342412450.jpg" target="_blank"><img src="http://img.blog.163.com/photo/-URfdygq9adNqt4gPzxbnw==/2014234933342412450.jpg"></a><br></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/24753220089785835612</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/24753220089785835612</guid>
    <pubDate>Tue, 7 Oct 2008 08:58:35 +0800</pubDate>
    <dcterms:modified>2008-10-07T08:58:35+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[奥运官方合作网站报道]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/24753220087905156495</link>
    <description><![CDATA[<div><P>2008年8月8日晚8点08分，整整等了一百多年的中华儿女、北京终于圆梦了。看奥运报道当然去官方网站了，号称技术驱动的官方网站竟然有地理岐视，但我是中国人啊。。。。看图说话</P>
<P><A href="http://img.blog.163.com/photo/m5rdrVkrGscVMFn92R6B1A==/325948023031747938.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/m5rdrVkrGscVMFn92R6B1A==/325948023031747938.jpg"></A></P>
<P>&nbsp;</P></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/24753220087905156495</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/24753220087905156495</guid>
    <pubDate>Sat, 9 Aug 2008 12:51:56 +0800</pubDate>
    <dcterms:modified>2008-08-09T12:51:56+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[Google搜索结果页改版了]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/24753220087194513328</link>
    <description><![CDATA[<div><P>Google搜索结果页改版啦，界面上看主要有三点：<BR>1、无厘头的上方LOGO重复了；如图<BR>2、搜索结果间距设大了，看起来清晰明朗，看来网易在这方面是最早抛弃密密麻麻的排版设计；<BR>3、下方的结果翻页有一个显著的改变，当前页突起来，以国内设计惯例，很快会有类似的模仿页面出现，我一年半前对文章页提出类似的方案，未获通过，有文章为证。<A href="http://blog.163.com/mike_gz/blog/static/247532200711510350798/">http://blog.163.com/mike_gz/blog/static/247532200711510350798/</A><BR><BR>翻页<BR><A href="http://img.blog.163.com/photo/MGy0Kw9Qm8ezPYU-iQq-lw==/4792111478499154381.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/MGy0Kw9Qm8ezPYU-iQq-lw==/4792111478499154381.jpg"></A></P>
<P>logo重复</P>
<P><A href="http://img.blog.163.com/photo/f8383pYUPRi-VsPkbNBOSw==/4792111478499154380.jpg" target=_blank><IMG src="http://img.blog.163.com/photo/f8383pYUPRi-VsPkbNBOSw==/4792111478499154380.jpg"></A></P></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/24753220087194513328</comments>
    <slash:comments>1</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/24753220087194513328</guid>
    <pubDate>Fri, 1 Aug 2008 09:45:13 +0800</pubDate>
    <dcterms:modified>2008-08-01T11:16:29+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[切尔西VS广州医药队]]></title>	
    <link>http://blog.163.com/mike_gz/blog/static/24753220086240357511</link>
    <description><![CDATA[<div><P>&nbsp;&nbsp;&nbsp;&nbsp; 昨天，也就是7月23日，切尔西亚洲之旅的第一场比赛在奥体中心举行，意外从同事手上得到一票，而且还是VIP票。下班吃完饭就赶过去，进场花了半个小时，找入口（VIP就是不同），安检特严。</P>
<P>&nbsp;&nbsp;&nbsp; 八点比赛准时进行，明显切尔西的实力高三个档次，好像是在半场演练，一脚传球、不看人传球、跑位、盘带、突破，精彩接连出现，让人真喊爽快，由于没有太多拼抢，上半场只取得一个进球，上半场结束我就退场了，警察同志把我的车分流到离球场比较远的地方停车，我怕结束时要排很久的队才能出来，很多很多车。</P></div>]]></description>
	    <author><![CDATA[罗西]]></author>
	    <comments>http://blog.163.com/mike_gz/blog/static/24753220086240357511</comments>
    <slash:comments>0</slash:comments>
    <guid isPermaLink="true">http://blog.163.com/mike_gz/blog/static/24753220086240357511</guid>
    <pubDate>Thu, 24 Jul 2008 12:35:07 +0800</pubDate>
    <dcterms:modified>2008-07-24T12:35:07+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  ta]]></title>	
    <link>http://img.bimg.126.net/photo/RbFjFw0uAV406DJtt99Z9g==/2833045640593940215.jpg</link>
    <description><![CDATA[<div>
			<a href="http://img.bimg.126.net/photo/RbFjFw0uAV406DJtt99Z9g==/2833045640593940215.jpg" target="_blank">
		<img src="http://img.bimg.126.net/photo/RbFjFw0uAV406DJtt99Z9g==/2833045640593940215.jpg" border="0" width="201" height="240" alt="ta 互联网研究 关注用户体验、产品策划、交互设计"/>
		</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[mike_gz]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/RbFjFw0uAV406DJtt99Z9g==/2833045640593940215.jpg</guid>
    <pubDate>Fri, 9 Jan 2009 12:05:34 +0800</pubDate>
    <dcterms:modified>2009-01-09T12:05:34+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  IMG_1064]]></title>	
    <link>http://img.bimg.126.net/photo/DLHv4D9cP0UvNG3uaPTNtA==/3737706215741516583.jpg</link>
    <description><![CDATA[<div>
			<a href="http://img.bimg.126.net/photo/DLHv4D9cP0UvNG3uaPTNtA==/3737706215741516583.jpg" target="_blank">
		<img src="http://img.bimg.126.net/photo/DLHv4D9cP0UvNG3uaPTNtA==/3737706215741516583.jpg" border="0" width="240" height="202" alt="IMG_1064 互联网研究 关注用户体验、产品策划、交互设计"/>
		</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[mike_gz]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/DLHv4D9cP0UvNG3uaPTNtA==/3737706215741516583.jpg</guid>
    <pubDate>Tue, 7 Oct 2008 08:57:14 +0800</pubDate>
    <dcterms:modified>2008-10-07T08:57:14+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  tt]]></title>	
    <link>http://img.bimg.126.net/photo/Yt2DowZhqMMcH-JcRMEyVA==/2860630188311224575.jpg</link>
    <description><![CDATA[<div>
			<a href="http://img.bimg.126.net/photo/Yt2DowZhqMMcH-JcRMEyVA==/2860630188311224575.jpg" target="_blank">
		<img src="http://img.bimg.126.net/photo/Yt2DowZhqMMcH-JcRMEyVA==/2860630188311224575.jpg" border="0" width="240" height="159" alt="tt 互联网研究 关注用户体验、产品策划、交互设计"/>
		</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[mike_gz]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/Yt2DowZhqMMcH-JcRMEyVA==/2860630188311224575.jpg</guid>
    <pubDate>Sat, 9 Aug 2008 12:50:22 +0800</pubDate>
    <dcterms:modified>2008-08-09T12:50:22+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[上传相片3张 ]]></title>	
    <link>http://blog.163.com/mike_gz/album</link>
    <description><![CDATA[<div>
				<a href="http://img.bimg.126.net/photo/sFDk0hgcSObv0sUNF4uubA==/2860348713334501722.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/sFDk0hgcSObv0sUNF4uubA==/2860348713334501722.jpg" border="0" width="240" height="180" alt="4009892518220426335 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/fgMqYvBaoqsze6fd1aX-Ig==/1762033354209558268.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/fgMqYvBaoqsze6fd1aX-Ig==/1762033354209558268.jpg" border="0" width="240" height="110" alt="2 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/f8383pYUPRi-VsPkbNBOSw==/4792111478499154380.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/f8383pYUPRi-VsPkbNBOSw==/4792111478499154380.jpg" border="0" width="212" height="156" alt="1 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[mike_gz]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/f8383pYUPRi-VsPkbNBOSw==/4792111478499154380.jpg</guid>
    <pubDate>Fri, 1 Aug 2008 09:43:13 +0800</pubDate>
    <dcterms:modified>2008-08-01T14:01:55+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[上传相片2张 ]]></title>	
    <link>http://blog.163.com/mike_gz/album</link>
    <description><![CDATA[<div>
				<a href="http://img.bimg.126.net/photo/AQbZ3HUUrKkaYLFkmU8d_w==/2568740637461847328.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/AQbZ3HUUrKkaYLFkmU8d_w==/2568740637461847328.jpg" border="0" width="208" height="240" alt="VN7W00100 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/VpDkn2xh_Q6Goa0kxT0wSg==/2568740637461847325.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/VpDkn2xh_Q6Goa0kxT0wSg==/2568740637461847325.jpg" border="0" width="160" height="240" alt="VN7W0010 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[mike_gz]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/VpDkn2xh_Q6Goa0kxT0wSg==/2568740637461847325.jpg</guid>
    <pubDate>Wed, 18 Jun 2008 09:26:02 +0800</pubDate>
    <dcterms:modified>2008-06-18T09:26:02+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[上传相片11张 ]]></title>	
    <link>http://blog.163.com/mike_gz/album</link>
    <description><![CDATA[<div>
				<a href="http://img.bimg.126.net/photo/lA18q6_2XPGhsnHjUcc2oQ==/5655395232071179996.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/lA18q6_2XPGhsnHjUcc2oQ==/5655395232071179996.jpg" border="0" width="240" height="180" alt="IMG_1011 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/G6Wi6gapSbO_vheizmPK2g==/5655395232071179988.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/G6Wi6gapSbO_vheizmPK2g==/5655395232071179988.jpg" border="0" width="240" height="180" alt="IMG_1010 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/xOQaYfTWDjUdGnmaAI8Iaw==/5655395232071179974.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/xOQaYfTWDjUdGnmaAI8Iaw==/5655395232071179974.jpg" border="0" width="240" height="180" alt="IMG_1009 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/9N3RwiO9sneb-5xVuPwuRw==/5655395232071179962.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/9N3RwiO9sneb-5xVuPwuRw==/5655395232071179962.jpg" border="0" width="240" height="180" alt="IMG_1008 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/pqG0qRO2JdmRTujjawFvRw==/5655395232071179953.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/pqG0qRO2JdmRTujjawFvRw==/5655395232071179953.jpg" border="0" width="240" height="180" alt="IMG_1007 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/tOqlwZe7qntKAbyZtJ7tjg==/576742227280864436.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/tOqlwZe7qntKAbyZtJ7tjg==/576742227280864436.jpg" border="0" width="240" height="180" alt="IMG_1006 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/Npo3bpmM6t9Kqj_pnhey9w==/1182757852138584888.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/Npo3bpmM6t9Kqj_pnhey9w==/1182757852138584888.jpg" border="0" width="240" height="153" alt="5 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/GHs542ZzXwSNWPY1sfp83w==/1182757852138584886.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/GHs542ZzXwSNWPY1sfp83w==/1182757852138584886.jpg" border="0" width="240" height="135" alt="4 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/qvPXro4g6yaJRkb0iZiaYg==/1182757852138584884.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/qvPXro4g6yaJRkb0iZiaYg==/1182757852138584884.jpg" border="0" width="240" height="189" alt="3 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/atlSbDkEKvBi9MNUgvsnNg==/1182757852138584882.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/atlSbDkEKvBi9MNUgvsnNg==/1182757852138584882.jpg" border="0" width="240" height="141" alt="2 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
			<a href="http://img.bimg.126.net/photo/CZ2WHt_gPychLep-ls02tw==/1182757852138584880.jpg" target="_blank">
			<img src="http://img.bimg.126.net/photo/CZ2WHt_gPychLep-ls02tw==/1182757852138584880.jpg" border="0" width="240" height="158" alt="1 互联网研究 关注用户体验、产品策划、交互设计"/>
			</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[mike_gz]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/CZ2WHt_gPychLep-ls02tw==/1182757852138584880.jpg</guid>
    <pubDate>Wed, 4 Jun 2008 16:14:43 +0800</pubDate>
    <dcterms:modified>2008-06-04T21:52:11+08:00</dcterms:modified>
  </item>    
  <item>
  	<title><![CDATA[相片:  t]]></title>	
    <link>http://img.bimg.126.net/photo/qhC151UmRW8m1BOKm93a1g==/2880614911657258043.jpg</link>
    <description><![CDATA[<div>
			<a href="http://img.bimg.126.net/photo/qhC151UmRW8m1BOKm93a1g==/2880614911657258043.jpg" target="_blank">
		<img src="http://img.bimg.126.net/photo/qhC151UmRW8m1BOKm93a1g==/2880614911657258043.jpg" border="0" width="240" height="180" alt="t 互联网研究 关注用户体验、产品策划、交互设计"/>
		</a><br/><br/>
</div>]]></description>
	    <author><![CDATA[mike_gz]]></author>
    <guid isPermaLink="false">http://img.bimg.126.net/photo/qhC151UmRW8m1BOKm93a1g==/2880614911657258043.jpg</guid>
    <pubDate>Mon, 2 Jun 2008 14:56:11 +0800</pubDate>
    <dcterms:modified>2008-06-02T14:56:11+08:00</dcterms:modified>
  </item>    
 </channel>
</rss>