<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Menjoy's 技术文摘</title>
    <description></description>
    <link>http://menjoy.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>SEO浓缩教程！ </title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/219050" style="color:red;">http://menjoy.javaeye.com/blog/219050</a>&nbsp;
          发表时间: 2008年07月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天在一个博友那里看到他转载的SEO浓缩教程，觉得不错，发上来更大家共享下！<br /><br />1.        尽量用独立IP和空间原因：同IP下其他网站受罚，可能会对你站有影响。如果你的站和很多垃圾、色情站同在一个服务器，搜索引擎会喜欢吗？<br />2.        做不同内容网站时，避免使用二级域名和免费域名。原因：当主域名或其他二级域名被惩罚，会牵连你的站。而且搜索引擎会规定每个域名下的收录数<br />3.        以复合关键字作域名，都应该用短横线隔开。如：www.made-in-china.com<br />原因：如果用www.madeinchina.com 搜索引擎会把madeinchina认为是一个词，而不是词组。<br />4.        在同等情况下，代表非商业性网站的后缀.org 和.net 有着比.com 更高的排名优势；对中文网站来说，表示中国域的.cn和.com.cn 又比无地区性的.com 有一定优势。<br />5.        网站核心关键字就是他们的经营范围，如产品/服务名称、行业定位，以及企业名称或品牌名称等。<br />6.        站在客户的角度考虑思考关键字<br />7.        将关键词扩展成一系列词组和短语。例如：交友－婚恋交友－聚餐交友－QQ交友－交友论坛等等。<br />8.        不要用热门关键字或定义太广泛的关键字，例如应避免直接用“交友”作为核心关键字。我的请客吃饭网选择了“聚餐交友”为核心关键字。<br />9.        使用地理位置+关键字：例如“上海交友”“上海聚餐交友”等。<br />10.    查看同类网站或对手所使用的关键字。<br />11.    绝对不要用和自己网站不相关的关键字。<br /><br /><br />12.    关键字数量：一页中最多别超过3个比较好。拥有不同的产品和服务的情况下，对每个产品进行单网页优化，而不是罗列在一个首页上。<br />13.    单页面关键字别低于2％，别超过7％。<br />14.    选择关键字一定要参考百度，例如：http://d.baidu.com/rs.php?q=交友<br />15.    关键字要无处不在，有重有轻，别把所有页面的关键字和密度都控制的几乎一样。<br />16.    TITLE、description、keywords内一定要有关键字，简短、明确就好，别太多或故意重复，并且阅读流畅。Description别太长，重点补充在title和keywords中未能充分表述的说明。<br />17.    关键词重点分布位置包括：页面靠顶部、左侧、标题、正文前 200 字以内。<br />18.    在导航、网站地图、锚文本中有意识使用关键字，例如：“首页”可以改成“请客吃饭首页”<br />19.    标题用&lt;H1>或&lt;B>，例如：&lt;h1>请客吃饭网公开测试啦&lt;/h1> <br />20.    图片alt中加关键字：例如：&lt;img src=http://www.url.com/image/logo.gif alt=”my LOGO”><br />21.    网站目录结构简短，文件名规范。URL别太长。<br />22.    大型网站目录尽量控制在4层以内，弄个“相关主题”栏目，加上深层页面的相关链接。<br />23.    在目录和文件名中使用关键字，用“-”分割词组，不要用“_”来分割。中文可用拼音。<br />24.    全站使用静态化，全部*.HTM或*.HTML。<br />25.    动态网站URL尽量不要出现：?  &  $  等。<br />26.    首页主要栏目在第一屏，用文字链接。<br />27.    在首页弄个“重点推荐”栏目，把次级目录中重要的内容链接放在这里。<br />28.    使用网站地图。每个页面链接别超过100个，超过的话可分页。<br />29.    别用框架，要用也用内联框架。<br />30.    图片尽量缩小尺寸，但保持清晰。<br />31.    在大图片上方或下方加上说明，例如“金瓶梅原著插图”。<br />32.    在图片周围加上包含关键字的链接，例如“更多金瓶梅插图”<br />33.    页面设计不要以FLASH为主，特别是首页，特别特别是商业网站首页！<br />34.    网页大小控制50K以内。太久大步开蜘蛛会以为你的站关了，呵呵。<br />35.    把CSS独立出去，使用独立CSS文件。<br />36.    把JS独立出去，使用独立JS文件。例如：&lt;script language=JavaScript src=misswe.js>&lt;/script><br />37.    JS代码比较少的话，可以放在页面底部，页面最上面保持HTML代码。<br />38.    向搜索引擎目录进行提交，YAHOO!目录、百度目录等等。Google 把来自 Yahoo 目录的链接作为网站排名的重要分值。<br />39.    上百个垃圾站过来的链接，不如一个高质量站或内容互补站的链接。<br />40.    别用自动登陆软件!别用群发软件! 被K了后悔都来不及。Google 就会对那些使用链接群发程序的站点进行永久性删除。百度会让你买竞价排名。<br />41.    链接质量分析：·来自以下网站的链接都可以称为高质量的链接：·搜索引擎目录中的链接以及已加入目录的网站的链接·与你的主题相关或互补的网站·PR 值不低于 4 的网站·流量大、知名度高、频繁更新的重要网站（如搜索引擎新闻源）·具有很少导出链接的网站·以你的关键词在搜索结果中排名前三页的网站·内容质量高的网站。<br />42.    不要和内容不相关的站点互连链接。如果导出链接站点内容与你的网站主题相关联，同样有利于搜索引擎友好。<br />43.    单页面导出链接不要超过15个。首页控制在10个以内。<br />44.    网站还可以通过建立多个内容相关的二级域名子站，彼此相链再一起链回主站，形成子站群包围主站，对提高排名相当有利。<br />45.    无论是导出链接、导入链接还是内部链接，都最好兼顾到链接文本中含有关键字。<br />46.    一个站的导入链接的文本完全相同，可能被搜索引擎误解，遭致忽略或惩罚。例如：“金瓶梅中文网”“金瓶梅解读”“金瓶梅原著欣赏”，都可以作为外部链接的文字内容。<br />47.    对中文网站来说，拥有3级PR是基础， 4级PR算达标，5级PR可谓良好，而6、7级PR就算相当优秀的网站。<br />48.    Google 默认 PDF 格式文件的 PR 天生为 3，因此，对于网站比较有价值的内容，建议做成 PDF 格式。例如：如果您的站和SEO有关，就可以把本笔记就可以做成PDF的 ^-^<br />49.    PR值的高低应该是包括 SEO 在内的搜索引擎营销所产生的自然结果而不应作为追求的目标。在 SEO 的过程中，不能忘记内容建设，不能忘记优质外链，但忘掉 PR 可没什么大不了的。<br />50.    沙盘效应：就是对新站的一个监督、熟悉的过程。如果你的网站在发布不久后以核心关键词在Google排名中出现由高走低的不稳定现象，多半是被Google请进了沙盒
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/219050#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 24 Jul 2008 14:04:45 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/219050</link>
        <guid>http://menjoy.javaeye.com/blog/219050</guid>
      </item>
      <item>
        <title>用prototype动态添加js脚本</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/161466" style="color:red;">http://menjoy.javaeye.com/blog/161466</a>&nbsp;
          发表时间: 2008年02月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在使用Ext过程中，js比较臃肿，如果单页做需要每个页面加载js，所以还是采取一个页面主程序，ext那几个庞大的js加载一次，不同的表格或Panel等EXT组件元素，进行适时加载，这样性能会好些吧，以下就是参考网上的用prototype动态加载js的代码<br /><br /><pre name="code" class="js">
var ajax = new Ajax.PeriodicalUpdater(
    'divid ',//存放欲加载js的页面元素ID
    'test.js',//请求的URL
    {
        method: 'post ',//HTTP请求的方式为POST
        evalScripts:true,//是否执行请求页面中的脚本
        frequency:1,//更新的频率
        decay:2//衰减系数
      }
);
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/161466#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 04 Feb 2008 23:44:50 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/161466</link>
        <guid>http://menjoy.javaeye.com/blog/161466</guid>
      </item>
      <item>
        <title>Ext中Proxy说明:HttpProxy/MemoryProxy/ScriptTagProxy </title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/156888" style="color:red;">http://menjoy.javaeye.com/blog/156888</a>&nbsp;
          发表时间: 2008年01月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Ext.data.DataProxy<br />数据代理类是一个纯虚类，主要用于生成Ext.data.Record对象，没有公开的属性和方法，只是归定子类需要处理三个事件<br />beforeload : ( Object This, Object params )<br />load : ( Object This, Object o, Object arg )<br />loadexception : ( Object This, Object o, Object arg, Object e )<br />事实上参数也是子类自定义的<br /><br />Ext.data.HttpProxy<br />api文档中说httpProxy是从object继承来的，事实上source中它和下面的Ext.data.MemoryProxy/Ext.data.ScriptTagProxy都继承于DataProxy<br />HttpProxy用于远程代理,而且服务端返回信息时必须指定Content-Type属性为"text/xml".<br /><br />HttpProxy( Object conn )<br />构造一个HttpProxy对象,参数可以是一个类似于{url: 'foo.php'}这样的json对象,也可以是一个Ext.data.Connection对象,如果参数没有指定，将使用Ext.Ajax对象将被用于发起请求<br /><br />getConnection() : Connection<br />得到当前连接对象<br /><br />load( Object params, Ext.data.DataReader reader, Function callback, Object scope, Object arg ) : void<br />从配置的connection对象得到record数据块，并激发callback<br />params:        发起http请求时所要传递到服务端的参数<br />DataReader:    见DataReader<br />callback:    回叫方法,第一个参数为接收到的信息,第二个参数为arg,第三个是成功标志<br />scope:        范围<br />arg:        这儿的参数将会传递给回叫函数callback<br /><br />使用示例:<br />var proxy=new Ext.data.HttpProxy({url:'datasource.xml'});<br />    //关于reader将会在Ext.data.DataReader中讲解<br />    var reader = new Ext.data.XmlReader({<br />       totalRecords: "results", <br />       record: "row",         <br />       id: "id"                 <br />    }, [<br />       {name: 'name', mapping: 'name'},<br />       {name: 'occupation'}            <br />    ]);<br />    <br />    //定义回叫方法<br />    var metadata;<br />    function callback(data,arg,success){<br />        if(success){<br />            metadata=data;<br />        }<br />    }<br />    //从connection配置的url中利用reader将返回的xml文件转为元数据,并传递给callback<br />    proxy.load( null,reader,callback,this);<br /><br />Ext.data.MemoryProxy<br />MemoryProxy( Object data )<br />构造<br />load( Object params, Ext.data.DataReader reader, Function callback, Object scope, Object arg ) : void<br />取数据，和HttpProxy类似,只是params参数没有被使用<br /><br />使用示例<br />var proxy=new Ext.data.MemoryProxy([ [1, 'Bill', 'Gardener'], [2, 'Ben', 'Horticulturalist'] ]); <br />var reader = new Ext.data.ArrayReader(<br />{id: 0}, <br />[<br />{name: 'name', mapping: 1},         <br />{name: 'occupation', mapping: 2}    <br />]);<br /><br />var metadata;<br />function callback(data,arg,success){<br />    metadata=data;<br />}<br />proxy.load( null,reader,callback,this);<br /><br /><br />Ext.data.ScriptTagProxy<br />这个类和HttpProxy类似，也是用于请求远程数据,但能用于跨主域调用,如果请求时使用了callback参数<br />则服务端应指定Content-Type属性为"text/javascript"<br />并返回callback(jsonobject)<br />反之则应置Content-Type属性为"application/x-json"<br />并直接返回json对象<br /><br />ScriptTagProxy( Object config )<br />构造,其中<br />config定义为{<br />callbackParam : String,    //回叫参数<br />nocache : Boolean,    //是否缓存<br />timeout : Number,    //超时<br />url : String        //请求数据的url<br />}<br /><br />abort() : void<br />放弃<br /><br />load( Object params, Ext.data.DataReader reader, Function callback, Object scope, Object arg ) : void<br />参见HttpProxy
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/156888#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jan 2008 14:16:12 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/156888</link>
        <guid>http://menjoy.javaeye.com/blog/156888</guid>
      </item>
      <item>
        <title>软件测试分类总结</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/153688" style="color:red;">http://menjoy.javaeye.com/blog/153688</a>&nbsp;
          发表时间: 2008年01月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small">和开发过程相对应，测试主要按照时间顺序经历单元测试、集成测试、系统测试、验收测试四个阶段。</span></p><p>&nbsp;</p><p><span style="font-size: medium; color: #993300"><strong>单元测试：</strong></span></p><p>&nbsp;</p><p><span style="font-size: small">是针对软件设计的最小单位&mdash;&mdash;程序模块进行正确性检验的测试工作，由开发人员进行，其目的在于发现每个程序模块内部可能存在的缺陷，实际程序员编码过程</span></p><p><span style="font-size: small">中已经进行了。单元测试基本不需要编写测试用例，开发人员自己调试通过、符合设计要求就可以了。</span></p><p>&nbsp;</p><p><span style="font-size: medium; color: #993300"><strong>集成测试：</strong></span></p><p>&nbsp;</p><p><span style="font-size: small">集成测试是将模块按照设计要求组装起来进行测试，主要目标是发现与接口有关的问题，由于在产品提交到测试部门前，产品开发小组都要进行联合调试，所以大部分企业是由开发人员来完成集成测试的，但也可以到了测试部门后再次进行集成测试。主要测试模块之间数据传输是否正确、模块集成后的功能是否实现、模块接口功能与设计需求是否一致。集成测试紧接在单元测试之后，当单元测试通过后，便可开始配置集成测试环境。集成测试是最关键的一步，如果问题较多就把产品送到测试部，会造成反复测试，从而浪费人力、物力资源，延误了工期。</span></p><p>&nbsp;</p><p><span style="font-size: medium; color: #993300"><strong>系统测试：</strong></span></p><p>&nbsp;</p><p><span style="font-size: small">系统测试是在集成测试通过后进行，目的是充分运行系统，验证各子系统是否都能正常工作并完成设计的要求。主要由测试部门进行，是测试部门最大最重要的一个测试，对产品的质量有重大的影响。系统测试的主要内容有：功能测试、健壮性测试、性能－效率测试、安全性测试、压力测试、可靠性测试、安装/反安装测试等。这个测试需要编写大量的测试用例，投入大量的资源来完成。主要由黑盒测试工程师在整个系统集成完毕后进行测试。前期测试系统的功能是否满足要求，后期测试系统运行的性能是否满足要求，以及系统在不同的软硬件环境中的兼容性等。系统测试主要依据《系统需求规格说明书》文档。</span></p><p><br /><span style="font-size: small">功能测试</span></p><p><span style="font-size: small">可细分为：逻辑功能测试、界面测试、易用性测试、安装测试、兼容性测试等。</span></p><p><br /><span style="font-size: small">性能测试</span></p><p><span style="font-size: small">是软件按测试的高端领域，主要包括时间性能和空间性能两种。</span></p><p><span style="font-size: small">时间性能：主要指软件的一个具体事物的响应时间。对于一个电子商务的网站来说，一个普遍接受的响应时间标准为2/5/10。 </span></p><p><span style="font-size: small">空间性能：主要指软件运行所消耗的系统资源。软件性能测试分为一般性能测试、稳定性能测试、负载测试和压力测试。</span></p><p><br /><span style="font-size: small">一般性能测试：</span></p><p><span style="font-size: small">让被测系统在正常的软硬件环境下运行，不向其施加任何压力的性能测试。比如，测试163邮箱的登陆模块，只让一fe用户多次登陆，记录服务器端系统资源的消耗情况（CPU、内存），并记录单个用户的平均登陆时间。</span></p><p><br /><span style="font-size: small">稳定性测试：</span></p><p><span style="font-size: small">连续运行被测系统，检查系统运行时的稳定程度。</span></p><p><br /><span style="font-size: small">负载测试：</span></p><p><span style="font-size: small">让被测系统在其能忍受的压力测试的极限范围内连续运行，来测试系统的稳定性。负载测试需要给被测系统施加其刚好能承受的压力。用系统能承受的压力值进行多次重复登陆，直到系统出现故障为止。</span></p><p><br /><span style="font-size: small">压力测试：</span></p><p><span style="font-size: small">持续不断地给被测系统增加压力，直到系统被压垮为止，用来测试系统所能承受的最大压力。假设一个人很轻松就能背1袋米，背两袋米很吃力，最多就能背3袋米，一般性测试&mdash;&mdash;我就让他背1袋米；稳定性测试&mdash;&mdash;我让他背1袋米，但让他去操场上跑圈，看多久累倒；负载测试&mdash;&mdash;我让他背2袋米去操场上跑圈，看多久累倒；压力测试&mdash;&mdash;我让他背2袋米、3袋米、4袋米&hellip;&hellip;发现他最多背3袋米。</span></p><p>&nbsp;</p><p><span style="font-size: medium; color: #993300"><strong>验收测试：</strong></span></p><p>&nbsp;</p><p><span style="font-size: small">根据需求阶段的《需求规格说明书》为验收标准，测试时要求模拟实际运行环境。对于实际项目可以和客户共同进行，对于产品实际就是最后一次的系统测试。测试内容为对功能模块的全面测试, 尤其要进行文档测试。功能测试：功能测试主要针对产品需求说明书的测试，主要是验证功能是否符合需求，包括原定功能的检验、是否有冗余功能、功能。这类测试应由测试员做，这并不意味着程序员在发布前不必检查他们的代码能否工作(自然他能用于测试的各个阶段)。 健壮性测试（容错能力/恢复能力测试）：侧重于程序容错能力的测试。本测试在单元测试阶段和系统测试阶段都要进行。如数据边界测试、非法数据测试、异常中断测试等等，主要是验证程序对各种异常情况是否进行正确处理。为了执行方便，建议健壮性的大部分测试用例尽量编写在功能测试用例中。</span></p><p>&nbsp;</p><p><span style="font-size: small">接口测试：</span></p><p><span style="font-size: small">程序员对各个模块进行系统联调的测试，包含程序内接口和程序外接口测试。这个测试，在单元测试阶段进行了一部分工作，而大部分都是在集成测试阶段完成的。由开发人员进行。 </span></p><p>&nbsp;</p><p><span style="font-size: small">强度测试：</span></p><p><span style="font-size: small">强度测试检查程序对异常情况的抵抗能力。强度测试总是迫使系统在异常的资源配置下运行。例如，①当中断的正常频率为每秒一至两个时，运行每秒产生十个中断的测试用例；②定量地增长数据输入率，检查输入子功能的反映能力；③运行需要最大存储空间（或其他资源）的测试用例；④运行可能导致虚存操作系统崩溃或磁盘数据剧烈抖动的测试用例，等等。</span></p><p>&nbsp;</p><p><span style="font-size: small">压力测试：</span></p><p><span style="font-size: small">对系统不断施加压力的测试，是通过确定一个系统的瓶颈或者不能接收的性能点，来获得系统能提供的最大服务级别的测试。例如测试一个 Web 站点在大量的负荷下，何时系统的响应会退化或失败。</span></p><p>&nbsp;</p><p><span style="font-size: small">性能测试：</span></p><p><span style="font-size: small">在交替进行负荷和强迫测试时常用的术语。性能测试关注的是系统的整体。它和通常所说的强度、压力/负载测试测试有密切关系。所以压力和强度测试应该于性能测试一同进行。举例说明：针对一个网站进行测试，模拟10到50个用户就是在进行常规性能测试，用户增加到1000乃至上万就变成了压力/负载测试。如果同时对系统进行大量的数据查询操作，就包含了强度测试。压力测试注重的是外界不断施压，强度测试注重的是极限或者异常情况下系统的测试。 </span></p><p><br /><span style="font-size: small">用户界面测试：</span></p><p><span style="font-size: small">对系统的界面进行测试，测试用户界面是否友好、是否方便易用、设计是否合理、位置是否正确等一系列界面问题</span></p><p>&nbsp;</p><p><span style="font-size: small">安全测试</span></p><p><span style="font-size: small">主要是测试系统在没有授权的内部或者外部用户对系统进行攻击或者恶意破坏时如何进行处理，是否仍能保证数据的安全。测试人员可以学习一些黑客技术，来对系统进行攻击。 </span></p><p>&nbsp;</p><p><span style="font-size: small">可靠性测试：</span></p><p><span style="font-size: small">这里是比较狭义的可靠性测试，它主要是对系统能否稳定运行进行一个统计，在实际工作中如果没有条件可以不必特意去做。重点做好与之紧密相关的功能测试、健壮性测试就可以了。 </span></p><p>&nbsp;</p><p><span style="font-size: small">安装/反安装测试：</span></p><p><span style="font-size: small">安装测试主要检验软件是否可以正确安装，安装文件的各项设置是否有效，安装后能否影响原系统；反安装是逆过程，测试是否删除干净，是否给影响原系统等。 </span></p><p>&nbsp;</p><p><span style="font-size: small">文档测试</span></p><p><span style="font-size: small">主要测试开发过程中针对用户的文档，以需求、用户手册、安装手册等为主，检验文档是否和实际应用存在差别。文档测试不需要编写测试用例。</span> </p><p>&nbsp;</p><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/153688#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 07 Jan 2008 16:02:16 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/153688</link>
        <guid>http://menjoy.javaeye.com/blog/153688</guid>
      </item>
      <item>
        <title>orcle重启</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/148428" style="color:red;">http://menjoy.javaeye.com/blog/148428</a>&nbsp;
          发表时间: 2007年12月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1. su - oracle -c "sqlplus ' / as sysdba'"<br />2. shutdown [nomal,immediate,abort]<br />3. startup
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/148428#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 14 Dec 2007 19:28:06 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/148428</link>
        <guid>http://menjoy.javaeye.com/blog/148428</guid>
      </item>
      <item>
        <title>破解Java程序</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/148151" style="color:red;">http://menjoy.javaeye.com/blog/148151</a>&nbsp;
          发表时间: 2007年12月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          第一步是定位，这也是最关键的一步，我们这里以Together For JBuilder Edition为例，启动Together，先看看长什么样子？喔，上来就问我要License；Ok，<br />每关系，退出；找到Together的启动Bat文件，找到它的启动命令：java .....，OK，在Java启动的时候给一个参数：“ -Xrunhprof:cpu=times”，保存，在启动，还是要<br />License，退出，这个时候，我们可以发现，在这个目录下多了一个“java.hprof.txt”文件，打开一看，就是我要的JVM的Dump文件，好多内容啊，没关系，慢慢看来。<br /><br />我们可以看见这个文件里面有好多熟悉的东西啊：java.*/com.sun.*/javax.*等等，但这个不是我们关心的，我们要的是com.togethersoft.*或者是一些没有包名的zd.d等等。（这里插一句，几乎所有的Java应用程序都会混淆的，其实混淆的原理也很简单，我们后面再说。）先找找有没有License有关的，Serach一下，嘿嘿，果然，474行：com.togethersoft.together.impl.ide.license.LicenseSetup.execute([DashoPro-V2-050200]:Unknown line)，Ok上那堆classpath中的Jar包里面找一下吧（推荐用WinRAR），找到了之后用Jad反编译，一看，这个没有混淆，但是用了一个zae的类，这个看名字就知道混淆过了，先不理它，再看看下面一句IdeLicenseAccess.setLicense(zae1)，Ok接着找到IdeLicenseAccess，哈哈，就这点名堂，所有的License验证都是走的这个类，面向对象的思想不错，呵呵：）<br /><br />定位定完了，接下来的事情就是按猜想的方法修改这两个类，屏蔽掉LicenseSetup里面execute方法的实际内容，修改IdeLicenseAccess，让多有的验证都返回true，然后编译，替换；不要高兴太早，这还没有完呢，要有责任心！！启动Together，果然，这下不要License了，有启动画面，进去了，但是一片灰色，怎么回事，一看控制台，一堆错，没关系，就怕不出错，查找根源，还有一个IdeLicenseUtil类出了问题，再反编译，修改，替换；这下搞定了。再启动，测试一下，OK。
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/148151#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 13 Dec 2007 17:36:18 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/148151</link>
        <guid>http://menjoy.javaeye.com/blog/148151</guid>
      </item>
      <item>
        <title>安装AWStats</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/147782" style="color:red;">http://menjoy.javaeye.com/blog/147782</a>&nbsp;
          发表时间: 2007年12月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、Linux平台<br />1、在http://awstats.sourceforge.net/ 网站上下载awstats-6.7-1.noarch.rpm或awstats-6.5.tar.gz安装包。<br />2、配置文件会自动生成在/etc/awstats下，其他网页、工具文件会在/usr/local/awstats下<br />3、#chown -R apache.apache /usr/local/awstats<br />#chmod +x /usr/local/awstats/wwwroot/cgi-bin/*<br />#chmod +x /usr/local/awstats/tools/*<br />#chmod +x /etc/awstats /*<br />#mkdir /var/lib/awstats   用于生成日志分析结果文件<br />#chmod +x /var/lib/awstats 即目录权限设为777，否则awstats页面的apache用户无法读写生成日志分析结果文件<br /> <br /> <br />4、Apache 发布awstats<br />awstats的脚本和静态文件缺省都在/usr/local/awstats/wwwroot/cgi-bin/目录下<br />因为安全原因，最好为awstats单独建立一个发布站点。<br />修改Apache配置文件httpd.conf<br />在最后新建虚拟主机<br />&lt;VirtualHost 10.0.0.1><br />ServerName www.sample.com<br />ErrorLog logs/www.sample.com-error_log<br />CustomLog logs/www.sample.com-access_log common<br />DocumentRoot /usr/local/awstats/wwwroot<br />DirectoryIndex awstats.pl<br />&lt;/VirtualHost><br />&lt;Directory /usr/local/awstats/wwwroot/cgi-bin><br />Options +ExecCGI<br />AddHandler cgi-script cgi pl<br />&lt;/Directory><br />最后用户可以通过http:// 10.0.0.1或者http:// www.sample.com去访问，还可以用apache加密功能，给该日志分析站点加密。<br /> <br />5、对于Apache：日志截断麻烦一点：需要安装cronolog工具<br />1.下载软件<br />　　http://cronolog.org/download/index.html<br />2.解压缩<br />　gzip -d cronolog-1.6.2.tar.gz<br />　tar xf cronolog-1.6.2.tar<br />3进入相应的目录<br />./configure<br />make<br />make install<br />4.cronolog安装完成以后需要对Apache进行适当配置，修改httpd.conf文件<br />自定义日志格式为（每日生成一个log）<br />CustomLog "|/usr/local/sbin/cronolog /var/log/httpd/ www.mydomain.com/access_log.%Y%m%d" combined<br />并将该目录（/var/log/httpd/）权限改为777，否则awstats页面的apache用户无法读取该目录下日志文件<br />　　如果存在多个虚拟站点<br />　　可以考虑在&lt;VirtualHost>中进行相应设置<br /> <br />6、对AWStats配置<br />1.#cd /usr/local/awstats/tools/<br />#./awstats_configure.pl<br />提示输入域名等，完成后在/etc/awstats会有对应域名的配置文件生成<br />接着修改它<br />#vi /etc/awstats/awstats.www.mydomain.com.conf<br />LogFile="/var/log/httpd/ www.mydomain.com/access_log. %YYYY-0%MM-0%DD-0 " <br />与Apache的httpd.conf修改的CustomLog一致<br />     <br />AllowToUpdateStatsFromBrowser=1  <br />主页上有手动“立即更新”按钮，默认为0，不出现<br />2. 如果有多个站点<br />手工拷贝上面配置文件为多个站点命名的配置文件<br />例如<br /># cp awstats.www.mydomain.com.conf awstats.www.mydomain2.com.conf<br />同样编辑该配置文件，加入对应得各个信息<br />LogFile "/var/log/httpd/www.mydomain2.com/access_log.%YYYY-24%MM-24%DD-24"<br />SiteName " www.mydomain2.com"<br /> <br />7、安装国家和城市插件<br />1.分别下载插件程序：<br />GeoIP：http://www.maxmind.com/download/geoip/api/c/<br />http://www.maxmind.com/download/geoip/api/perl/<br /> <br />GeoIP安装：<br />先下载C库：GeoIP C解包后<br />%./configure; make<br />#make install<br /> <br />然后下载Perl库：GeoIP Perl解包后<br />%perl MakeFile.PL; make<br />#make install<br /> <br /> <br />2.再下载GeoIP/GeoIPCityLite两个信息数据包：<br />http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz<br />http://www.maxmind.com/download/geoip/database/GeoIP.dat.gz<br />解包并部署到/usr/local/awstats目录下<br />编辑awstats的配置文件：<br />#vi /etc/awstats/awstats.www.mydomain.com.conf<br />修改其中的一些配置选项为：<br />LoadPlugin="decodeutfkeys"<br />LoadPlugin="geoip GEOIP_STANDARD /usr/local/awstats /GeoIP.dat"<br />LoadPlugin="geoip_city_maxmind GEOIP_STANDARD /usr/local/awstats /GeoLiteCity.dat"<br /> <br />3.如果出现无法调用.so文件或者其他共享文件错误<br />编辑/etc/ld.so.conf，在其中加入一行<br />/usr/local/lib<br />之后再执行<br />/sbin/ldconfig /etc/ld.so.conf<br /> <br /> <br />8、启动awstats<br />1.手动生成日志分析文件<br />#/usr/local/awstats/tools/awstats_updateall.pl now<br />2.自动生成日志分析文件<br />在crond加入<br />#vi /etc/crontab<br />添加：<br />*/5 * * * * root /usr/local/awstats/tools/awstats_updateall.pl now<br />（每5分钟更新日志分析文件）
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/147782#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Dec 2007 13:26:59 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/147782</link>
        <guid>http://menjoy.javaeye.com/blog/147782</guid>
      </item>
      <item>
        <title>JS控件--带时间</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/146272" style="color:red;">http://menjoy.javaeye.com/blog/146272</a>&nbsp;
          发表时间: 2007年12月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在网上找的，觉得不错，收留之
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/146272#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 05 Dec 2007 18:42:09 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/146272</link>
        <guid>http://menjoy.javaeye.com/blog/146272</guid>
      </item>
      <item>
        <title>JS中常用的xpath特性</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/131965" style="color:red;">http://menjoy.javaeye.com/blog/131965</a>&nbsp;
          发表时间: 2007年10月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="code_title">js 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-c">
    <li class="alt"><span><span class="comment">//选择所有dir元素的值等于xx的元素 </span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;server/dir[text()='xx']&quot;</span><span>) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="comment">//选择server元素下的所有dir元素： </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;server/dir&quot;</span><span>) &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="comment">//选择server元素下的第一个dir元素： </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>Dom.documentElement.selectSingleNode(</span><span class="string">&quot;server/dir&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="comment">//选择server元素下accesstype等于3的多有dir元素： </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;server/dir[@accesstype=\&quot;3\&quot;]&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="comment">//选择server元素下第一个dir元素： </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;server[postion()&nbsp;=1]/dir&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;server/dir[1]&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="comment">//选择server元素下最后一个dir元素： </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;server/dir[last()]&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="comment">//选择有三个祖先元素的file元素： </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;*/*/*/file&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span></span><span class="comment">//选择有id属性的dir元素： </span><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;/dir[@id]&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li class=""><span></span><span class="comment">//选择含有2个dir子元素的元素 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>Dom.documentElement.selectNodes(</span><span class="string">&quot;/*[count(dir)=2]&quot;</span><span>);&nbsp;&nbsp;</span></li>
</ol>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/131965#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 15 Oct 2007 14:57:07 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/131965</link>
        <guid>http://menjoy.javaeye.com/blog/131965</guid>
      </item>
      <item>
        <title>JavaScript 面向对象程序设计（上）——封装</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/127863" style="color:red;">http://menjoy.javaeye.com/blog/127863</a>&nbsp;
          发表时间: 2007年09月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>JavaScript 是一种非常灵活的面向对象程序设计语言，它与传统的强类型的面向对象程序设计语言（如 C++，Java，C# 等）有很大不同，所以要实现如 C++、java、C# 当中的一些特性就需要换一种思考方式来解决。今天主要讨论如何在 JavaScript 脚本中实现数据的封装（encapsulation）。</p>
<p>数据封装说的简单点就是把不希望调用者看见的内容隐藏起来。它是面向对象程序设计的三要素之首，其它两个是继承和多态，关于它们的内容在后面再讨论。</p>
<p>关于数据封装的实现，在 C++、Java、C# 等语言中是通过 public、private、static 等关键字实现的。在 JavaScript 则采用了另外一种截然不同的形式。在讨论如何具体实现某种方式的数据封装前，我们先说几个简单的，大家所熟知却又容易忽略的 JavaScript 的概念。</p>
<h1>1 几个基本概念</h1>
<h2>1.1 变量定义</h2>
<p>在 JavaScript 语言中，是通过 var 关键字来定义变量的。</p>
<p>但是如果我们直接给一个没有使用 var 定义的变量赋值，那么这个变量就会成为全局变量。</p>
<p>一般情况下，我们应该避免使用没有用 var 定义的变量，主要原因是它会影响程序的执行效率，因为存取全局变量速度比局部变量要慢得多。</p>
<p>但是这种用法可以保证我们的变量一定是全局变量。</p>
<p>另外，为了保证速度，我们在使用全局变量时，可以通过 var 定义一个局部变量，然后将全局变量赋予之，由此可以得到一个全局变量的局部引用。</p>
<h2>1.2 变量类型</h2>
<p>没有定义的变量，类型为 undefined。</p>
<p>变量的值可以是函数。</p>
<p>函数在 JavaScript 中可以充当类的角色。</p>
<h2>1.3 变量作用域</h2>
<p>变量作用域是指变量生存周期的有效范围。</p>
<p>单纯用 { } 创建的块不能创建作用域。</p>
<p>with 将它包含的对象作用域添加到当前作用域链中，但 with 不创建新的作用域。with 块结束后，会将对象作用域从当前作用域链中删除。</p>
<p>try-catch 中，catch 的错误对象只在 catch 块中有效，但 catch 块中定义的变量属于当前作用域。</p>
<p>其它如 if、for、for-in、while、do-while、switch 等控制语句创建的块不能创建作用域。</p>
<p>用 function 创建的函数，会创建一个新的作用域添加到当前作用域中。<br />
</p>
<h1>2 封装</h1>
<p>下面我们就来讨论具体的封装。首先说一下大家最熟悉的几种封装：私有实例成员、公有实例成员和公有静态成员。最后会讨论一下大家所不熟悉的私有静态成员和静态类的封装办法。因为下面要讨论的是面向对象编程，所有当函数作为类来定义和使用时，我们暂且将其成为类。</p>
<h2>2.1 私有实例成员</h2>
<p>私有实例成员在 JavaScript 中实际上可以用函数内的局部变量来实现，它相当于类的私有实例成员。例如：</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: blue">class1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// constructor</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">o</span><span style="COLOR: gray"> = </span><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: blue">class1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: #ffa500">// error</span> </li>
    <li><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span></li>
</ol>
</div>
<p>这里 m_first 和 m_second 是 class1 的两个私有实例字段，method1 和 method2 是两个私有实例方法。他们只能在该类的对象内部被使用，在对象外无法使用。</p>
<p>这里大家会发现创建私有方法有两种方式，一种是直接在类中定义方法，另一种是先定义一个局部变量（私有实例字段），然后定义一个匿名方法赋值给它。</p>
<p>直接在类中定义方法，则该方法的作用域就是这个类，因此这个方法在此类外不能够被访问，而它又可以存取类中所有的私有实例字段，这就保证了这是个私有实例方法。</p>
<p>第二种创建私有实例方法的方式跟第一种方式的效果是一样的，但是第二种方式更灵活一些。</p>
<p>你应该还会注意到，class1 中把构造器代码用 { } 括起来了，这样做虽然没有必要，但是代码看上去更加清晰。</p>
<p>关于这段构造器代码，还有两点需要说明的地方：</p>
<p>1、构造器代码必须放在整个类定义的最后，这样做是为了保证在它当中被调用的方法都已经被定义了。因为 JavaScript 是解释型语言，所以，它会按照从上到下的顺序执行，因此，如果构造器代码放在其它方法定义的前面，则执行到调用语句时找不到要调用的方法，就会出错。</p>
<p>2、我们已经知道 { } 创建的块不会改变作用域，因此如果在这样的构造器代码中创建局部变量，实际上是在整个类中创建私有实例成员，所以，如果需要用到局部变量，应当定义一个私有实例方法，例如可以命名为 constructor()，在 constructor() 这个私有实例方法中定义局部变量和原来 { } 构造器中要执行的代码，然后在类的最后直接调用它就可以了。所以更好的写法是这样的：</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: blue">class1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">constructor</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">constructor</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">o</span><span style="COLOR: gray"> = </span><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: blue">class1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: #ffa500">// error</span> </li>
    <li><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span></li>
</ol>
</div>
<p>最后，你可能还会发现 class1 的定义我们没有用 var，这样做我们就可以保证它是个全局的类了。<br />
</p>
<h2>2.2 公有实例成员</h2>
<p>公有实例成员可以通过两种方式来创建，我们先来看下面这个例子：</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: blue">class2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">first</span><span style="COLOR: gray"> = </span><span style="COLOR: #8b0000">&quot;</span><span style="COLOR: red">first</span><span style="COLOR: #8b0000">&quot;</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">second</span><span style="COLOR: gray"> = </span><span style="COLOR: olive">[</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">s</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">e</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">c</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">o</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">n</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">d</span><span style="COLOR: #8b0000">'</span><span style="COLOR: olive">]</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: gray"> = </span><span style="COLOR: blue">method2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// constructor</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: #ffa500">// public method</span> </li>
    <li><span style="COLOR: blue">class1</span><span style="COLOR: gray">.</span><span style="COLOR: blue">prototype</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method3</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">o</span><span style="COLOR: gray"> = </span><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: blue">class2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method3</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">o</span><span style="COLOR: gray">.</span><span style="COLOR: blue">first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span></li>
</ol>
</div>
<p>我们发现这个例子是在 class1 的例子上做了一些补充。给它添加了公有实例字段和公有实例方法，我们把它们通称为公有实例成员。</p>
<p>我们应该已经发现，创建公有实例成员其实很简单，一种方式是通过在类中给 this.<em>memberName</em> 来赋值，如果值是函数之外的类型，那就是个公有实例字段，如果值是函数类型，那就是公有实例方法。另外一种方式则是通过给 <em>className</em>.prototype.<em>memberName</em> 赋值，可赋值的类型跟 this.<em>memberName</em> 是相同的。</p>
<p>到底是通过 this 方式定义好呢，还是通过 prototype 方式定义好呢？</p>
<p>其实它们各有各的用途，它们之间不是谁比谁更好的关系。在某些情况下，我们只能用其中特定的一种方式来定义公有实例成员，而不能够使用另一种方式。原因在于它们实际上是有区别的：</p>
<p>1、prototype 方式只应该在类外定义。this 方式只能在类中定义。</p>
<p>2、prototype 方式如果在类中定义时，则存取私有实例成员时，总是存取最后一个对象实例中的私有实例成员。</p>
<p>3、prototype 方式定义的公有实例成员是创建在类的原型之上的成员。this 方式定义的公有实例成员，是直接创建在类的实例对象上的成员。</p>
<p>基于前两点区别，我们可以得到这样的结论：如果要在公有实例方法中存取私有实例成员，那么必须用 this 方式定义。</p>
<p>关于第三点区别，我们后面在讨论继承时再对它进行更深入的剖析。这里只要知道有这个区别就可以了。</p>
<p>我们还会发现，公有实例成员和私有实例成员名字是可以相同的，这样不会有冲突吗？</p>
<p>当然不会。原因在于它们的存取方式不同，公有实例成员在类中存取时，必须要用 this. 前缀来引用。而私有实例成员在类中存取时，不使用也不能够使用 this. 前缀来存取。而在类外存取时，只有公有成员是可以通过类的实例对象存取的，私有成员无法存取。<br />
</p>
<h2>2.3 公有静态成员</h2>
<p>公有静态成员的定义很简单，例如：</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: blue">class3</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// constructor</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: #ffa500">// public static field</span> </li>
    <li><span style="COLOR: blue">class3</span><span style="COLOR: gray">.</span><span style="COLOR: blue">field1</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: #ffa500">// public static method</span> </li>
    <li><span style="COLOR: blue">class3</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">class3</span><span style="COLOR: gray">.</span><span style="COLOR: blue">field1</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: blue">class3</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span></li>
</ol>
</div>
<p>这个例子的 class3 跟 class1 很像。不同的是 class3 的外面，我们又给 class3 定义了一个静态字段和静态方法。</p>
<p>定义的方式就是给 <em>className</em>.<em>memberName</em> 直接赋值。</p>
<p>这里定义的静态字段和静态方法都是可以被直接通过类名引用来存取的，而不需要创建对象。因此它们是公有静态成员。</p>
<p>不过有点要记住，一定不要将公有静态成员定义在它所在的类的内部，否则你会得到非你所期望的结果。我们可以看下面这个例子：</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: blue">class4</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_second</span><span style="COLOR: gray">++;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">s_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">o1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: blue">class4</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// 2</span> </li>
    <li><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">; </span></li>
    <li><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// 3 </span></li>
    <li><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">o2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: blue">class4</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// 2 </span></li>
    <li><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">class4</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// 3</span></li>
</ol>
</div>
<p>这个例子中，我们期望 s_second 能够扮演一个私有静态成员的角色，但是输出结果却不是我们所期望的。我们会发现 s_second 实际上是 class4 的一个私有实例成员，而不是私有静态成员。而 class4 的 method1 和 method2 所存取的私有成员总是类的最后一个实例对象中的这个私有实例成员。</p>
<p>问题出在哪儿呢？</p>
<p>问题出在每次通过 new class4() 创建一个对象实例时，class4 中的所有语句都会重新执行，因此，s_second 被重置，并成为新对象中的一个私有实例成员。而 class4.method1 和 class4.method2 也被重新定义了，而这个定义也将它们的变量作用域切换到了最后一个对象上来。这与把通过 prototype 方式创建的公有实例方法定义在类的内部而产生的错误是一样的。</p>
<p><strong>所以，一定不要将公有静态成员定义在它所在的类的内部！也不要把通过 prototype 方式创建的公有实例方法定义在类的内部！</strong></p>
<p>那如何定义一个私有静态成员呢？<br />
</p>
<h2>2.4 私有静态成员</h2>
<p>前面在基本概念里我们已经清楚了，只有用 function 创建函数，才能创建一个新的作用域，而要创建私有成员（不论是静态成员，还是实例成员），都需要通过创建新的作用域才能够起到数据隐藏的目的。下面所采用的方法就是基于这一点来实现的。</p>
<p>实现私有静态成员是通过创建一个匿名函数函数来创建一个新的作用域来实现的。</p>
<p>通常我们使用匿名函数时都是将它赋值给一个变量，然后通过这个变量引用该匿名函数。这种情况下，该匿名函数可以被反复调用或者作为类去创建对象。而这里，我们创建的匿名函数不赋值给任何变量，在它创建后立即执行，或者立即实例化为一个对象，并且该对象也不赋值给任何变量，这种情况下，该函数本身或者它实例化后的对象都不能够被再次存取，因此它唯一的作用就是创建了一个新的作用域，并隔离了它内部的所有局部变量和函数。因此，这些局部变量和函数就成了我们所需要的私有静态成员。而这个立即执行的匿名函数或者立即实例化的匿名函数我们称它为静态封装环境。</p>
<p>下面我们先来看通过直接调用匿名函数方式来创建带有私有静态成员的类的例子：</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: blue">class5</span><span style="COLOR: gray"> = </span><span style="COLOR: olive">(</span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private static fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private static methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_first</span><span style="COLOR: gray">++;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">constructor</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">first</span><span style="COLOR: gray"> = </span><span style="COLOR: #8b0000">&quot;</span><span style="COLOR: red">first</span><span style="COLOR: #8b0000">&quot;</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">second</span><span style="COLOR: gray"> = </span><span style="COLOR: olive">[</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">s</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">e</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">c</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">o</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">n</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">d</span><span style="COLOR: #8b0000">'</span><span style="COLOR: olive">]</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_second</span><span style="COLOR: gray">--;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// constructor</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public static methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">constructor</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_first</span><span style="COLOR: gray">++;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">s_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">constructor</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">s_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">return</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">constructor</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: olive">})()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">o1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: blue">class5</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">class5</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">class5</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">o1</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">o2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: blue">class5</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">class5</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">class5</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: blue">o2</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span></li>
</ol>
</div>
<p>这个例子中，通过</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: olive">(</span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; ...</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">contructor</span><span style="COLOR: gray"> </span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; ...</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">return</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">constructor</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: olive">})()</span><span style="COLOR: gray">;</span></li>
</ol>
</div>
<p>来创建了一个静态封装环境，实际的类是在这个环境中定义的，并且在最后通过 return 语句将最后的类返回给我们的全局变量 class5，然后我们就可以通过 class5 来引用这个带有静态私有成员的类了。</p>
<p>为了区分私有静态成员和私有实例成员，我们在私有静态成员前面用了 s_ 前缀，在私有实例成员前面加了 m_ 前缀，这样避免了重名，因此在对象中总是可以存取私有静态成员的。</p>
<p>但是这种命名方式不是必须的，只是推荐的，私有静态成员可以跟私有实例成员同名，在重名的情况下，在类构造器和在类中定义的实例方法中存取的都是私有实例成员，在静态方法（不论是公有静态方法还是私有静态方法）中存取的都是私有静态成员。</p>
<p>在类外并且在静态封装环境中通过 prototype 方式定义的公有实例方法存取的是私有静态成员。</p>
<p>在静态封装环境外定义的公有静态方法和通过 prototype 方式定义的公有实例方法无法直接存取私有静态成员。</p>
<p>另外一种方式通过直接实例化匿名函数方式来创建带有私有静态成员的类的例子跟上面的例子很相似：</p>
<div class="hl-surround">
<ol title="Double click to hide line number." class="hl-main ln-show" ondblclick="linenumber(this)">
    <li class="hl-firstline"><span style="COLOR: green">new</span><span style="COLOR: gray"> </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private static fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private static methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_first</span><span style="COLOR: gray">++;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">s_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">class6</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_first</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">1</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">m_second</span><span style="COLOR: gray"> = </span><span style="COLOR: maroon">2</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// private methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">function</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">var</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray"> </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">m_second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public fields</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">first</span><span style="COLOR: gray"> = </span><span style="COLOR: #8b0000">&quot;</span><span style="COLOR: red">first</span><span style="COLOR: #8b0000">&quot;</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">second</span><span style="COLOR: gray"> = </span><span style="COLOR: olive">[</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">s</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">e</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">c</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">o</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">n</span><span style="COLOR: #8b0000">'</span><span style="COLOR: gray">,</span><span style="COLOR: #8b0000">'</span><span style="COLOR: red">d</span><span style="COLOR: #8b0000">'</span><span style="COLOR: olive">]</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_second</span><span style="COLOR: gray">--;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">second</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: #ffa500">// constructor</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: green">this</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: olive">()</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: #ffa500">// public static methods</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">class6</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method1</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">s_first</span><span style="COLOR: gray">++;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">s_first</span><span style="COLOR: olive">)</span><span style="COLOR: gray">;</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: olive">}</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; </span><span style="COLOR: blue">class6</span><span style="COLOR: gray">.</span><span style="COLOR: blue">method2</span><span style="COLOR: gray"> = </span><span style="COLOR: green">function</span><span style="COLOR: olive">()</span><span style="COLOR: gray">&nbsp;</span><span style="COLOR: olive">{</span> </li>
    <li><span style="COLOR: gray">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="COLOR: blue">alert</span><span style="COLOR: olive">(</span><span style="COLOR: blue">s_seco</span></li></ol></div>
          <br/>
          <span style="color:red;">
            <a href="http://menjoy.javaeye.com/blog/127863#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 28 Sep 2007 12:00:52 +0800</pubDate>
        <link>http://menjoy.javaeye.com/blog/127863</link>
        <guid>http://menjoy.javaeye.com/blog/127863</guid>
      </item>
      <item>
        <title>JavaScript 面向对象程序设计（下）——继承与多态</title>
        <author>menjoy</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://menjoy.javaeye.com">menjoy</a>&nbsp;
          链接：<a href="http://menjoy.javaeye.com/blog/127847" style="color:red;">http://menjoy.javaeye.com/blog/127847</a>&nbsp;
          发表时间: 2007年09月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1 又是几个基本概念<br />为什么要说又呢？  <br /><br />在讨论继承时，我们已经列出了一些基本概念了，那些概念是跟封装密切相关的概念，今天我们要讨论的基本概念，主要是跟继承与多态相关的，但是它们跟封装也有一些联系。<br /><br />1.1 定义和赋值<br />变量定义是指用 <br /><br />var a;<br />这种形式来声明变量。<br /><br />函数定义是指用 <br /><br />function a(...) {...}<br />这种形式来声明函数。<br /><br />var a = 1;<br />是两个过程。第一个过程是定义变量 a，第二个过程是给变量 a 赋值。<br /><br />同样<br /><br />var a = function(...) {};<br />也是两个过程，第一个过程是定义变量 a 和一个匿名函数，第二个过程是把匿名函数赋值给变量 a。<br /><br />变量定义和函数定义是在整个脚本执行之前完成的，而变量赋值是在执行阶段完成的。<br /><br />变量定义的作用仅仅是给所声明的变量指明它的作用域，变量定义并不给变量初始值，任何没有定义的而直接使用的变量，或者定义但没有赋值的变量，他们的值都是 undefined。<br /><br />函数定义除了声明函数所在的作用域外，同时还定义函数体结构。这个过程是递归的，也就是说，对函数体的定义包括了对函数体内的变量定义和函数定义。<br /><br />通过下面这个例子我们可以更明确的理解这一点：<br /><br /><pre name="code" class="java">alert(a);
alert(b);
alert(c);
var a = "a";
function a() {}
function b() {}
var b = "b";
var c = "c";
var c = function() {}
alert(a);
alert(b);
alert(c);</pre><br /><br />猜猜这个程序执行的结果是什么？然后执行一下看看是不是跟你想的一样，如果跟你想的一样的话，那说明你已经理解上面所说的了。<br /><br />这段程序的结果很有意思，虽然第一个 alert(a) 在最前面，但是你会发现它输出的值竟然是 function a() {}，这说明，函数定义确实在整个程序执行之前就已经完成了。<br /><br />再来看 b，函数 b 定义在变量 b 之前，但是第一个 alert(b) 输出的仍然是 function b() {}，这说明，变量定义确实不对变量做什么，仅仅是声明它的作用域而已，它不会覆盖函数定义。<br /><br />最后看 c，第一个 alert(c) 输出的是 undefined，这说明 var c = function() {} 不是对函数 c 定义，仅仅是定义一个变量 c 和一个匿名函数。<br /><br />再来看第二个 alert(a)，你会发现输出的竟然是 a，这说明赋值语句确实是在执行过程中完成的，因此，它覆盖了函数 a 的定义。<br /><br />第二个 alert(b) 当然也一样，输出的是 b，这说明不管赋值语句写在函数定义之前还是函数定义之后，对一个跟函数同名的变量赋值总会覆盖函数定义。<br /><br />第二个 alert(c) 输出的是 function() {}，这说明，赋值语句是顺序执行的，后面的赋值覆盖了前面的赋值，不管赋的值是函数还是其它对象。<br /><br />理解了上面所说的内容，我想你应该知道什么时候该用 function x(..) {…}，什么时候该用 var x = function (…) {…} 了吧？<br /><br />最后还要提醒一点，eval 中的如果出现变量定义和函数定义，则它们是在执行阶段完成的。所以，不到万不得已，不要用 eval！另外，即使要用 eval，也不要在里面用局部变量和局部方法！<br /><br />1.2 this 和执行上下文<br />在前面讨论封装时，我们已经接触过 this 了。在对封装的讨论中，我们看到的 this 都是表示 this 所在的类的实例化对象本身。真的是这样吗？<br /><br />先看一下下面的例子吧：<br /><br /><pre name="code" class="java">var x = "I'm a global variable!";
function method() {
    alert(x);
    alert(this.x);
}
function class1() {
    // private field
    var x = "I'm a private variable!";
    // private method
    function method1() {
        alert(x);
        alert(this.x);
    }
    var method2 = method;
    // public field
    this.x = "I'm a object variable!";
    // public method
    this.method1 = function() {
        alert(x);
        alert(this.x);
    }
    this.method2 = method;
    // constructor
    {
        this.method1();     // I'm a private variable!
                            // I'm a object variable!
        this.method2();     // I'm a global variable!
                            // I'm a object variable!
        method1();          // I'm a private variable!
                            // I'm a global variable!
        method2();          // I'm a global variable!
                            // I'm a global variable!
        method1.call(this); // I'm a private variable!
                            // I'm a object variable!
        method2.call(this); // I'm a global variable!
                            // I'm a object variable!
    }
}
 
var o = new class1();
method();       // I'm a global variable!
                // I'm a global variable!
o.method1();    // I'm a private variable!
                // I'm a object variable!
o.method2();    // I'm a global variable!
                // I'm a object variable!</pre><br /><br />为什么是这样的结果呢？<br /><br />那就先来看看什么是执行上下文吧。那什么是执行上下文呢？<br /><br />如果当前正在执行的是一个方法，则执行上下文就是该方法所附属的对象，如果当前正在执行的是一个创建对象（就是通过 new 来创建）的过程，则创建的对象就是执行上下文。<br /><br />如果一个方法在执行时没有明确的附属于一个对象，则它的执行上下文是全局对象（顶级对象），但它不一定附属于全局对象。全局对象由当前环境来决定。在浏览器环境下，全局对象就是 window 对象。<br /><br />定义在所有函数之外的全局变量和全局函数附属于全局对象，定义在函数内的局部变量和局部函数不附属于任何对象。<br /><br />那执行上下文跟变量作用域有没有关系呢？<br /><br />执行上下文与变量作用域是不同的。<br /><br />一个函数赋值给另一个变量时，这个函数的内部所使用的变量的作用域不会改变，但它的执行上下文会变为这个变量所附属的对象（如果这个变量有附属对象的话）。<br /><br />Function 原型上的 call 和 apply 方法可以改变执行上下文，但是同样不会改变变量作用域。<br /><br />要理解上面这些话，其实只需要记住一点：<br /><br />变量作用域是在定义时就确定的，它永远不会变；而执行上下文是在执行时才确定的，它随时可以变。<br /><br />这样我们就不难理解上面那个例子了。this.method1() 这条语句（注意，这里说的还没有进入这个函数体）执行时，正在创建对象，那当前的执行上下文就是这个正在创建的对象，所以 this 指向的也是当前正在创建的对象，在 this.method1() 这个方法执行时（这里是指进入函数体），这个正在执行的方法所附属的对象也是这个正在创建的对象，所以，它里面 this.x 的 this 也是同一个对象，所以你看的输出就是 I’m a object variable! 了。<br /><br />而在执行 method1() 这个函数时（是指进入函数体后），method1() 没有明确的附属于一个对象，虽然它是定义在 class1 中的，但是他并没有不是附属于 class1 的，也不是附属于 class1 实例化后的对象的，只是它的作用域被限制在了 class1 当中。因此，它的附属对象实际上是全局对象，因此，当在它当中执行到 alert(this.x) 时，this.x 就成了我们在全局环境下定义的那个值为 “I’m a global variable!” 的 x 了。<br /><br />method2() 虽然是在 class1 中定义的，但是 method() 是在 class1 之外定义的，method 被赋值给 method2 时，并没有改变 method 的作用域，所以，在 method2 执行时，仍然是在 method 被定义的作用域内执行的，因此，你看到的就是两个 I’m a global variable! 输出了。同样，this.method2() 调用时，alert(x) 输出 I’m a global variable! 也是这个原因。<br /><br />因为 call 会改变执行上下文，所以通过 method1.call(this) 和 method2.call(this) 时，this.x 都变成了 I’m a object variable!。但是它不能改变作用域，所以 x 仍然跟不使用 call 方法调用时的结果是一样的。<br /><br />而我们后面执行 o.method1() 时，alert(x) 没有用 this 指出 x 的执行上下文，则 x 表示当前执行的函数所在的作用域中最近定义的变量，因此，这时输出的就是 I’m a private variable!。最后输出 I’m a object variable! 我想不用我说大家也知道为什么了吧？:D<br /><br />2 继承和多态<br />2.1 从封装开始<br />前面我们说了，封装的目的是实现数据隐藏。<br /><br />但是更深一层来说，在 javascript 中进行封装还有以下几个好处：<br /><br />1、隐身实现细节，当私有部分的实现完全重写时，并不需要改变调用者的行为。这也是其它面向对象语言要实现封装的主要目的。<br /><br />2、javascript 中，局部变量和局部函数访问速度更快，因此把私有字段以局部变量来封装，把私有方法以局部方法来封装可以提高脚本的执行效率。<br /><br />3、对于 javascript 压缩混淆器（据我所知，目前最好的 javascript 分析、压缩、混淆器就是 JSA）来说，局部变量和局部函数名都是可以被替换的，而全局变量和全局函数名是不可以被替换的（实际上，对于 javascript 脚本解析器工作时也是这样的）。因此，不论对于开源还是非开源的 javascript 程序，当私有字段和私有方法使用封装技术后，编写代码时就可以给它们定义足够长的表意名称，增加代码的可读性，而发布时，它们可以被替换为一些很短的名称（一般是单字符名称），这样就可以得到充分的压缩和混淆。及减少了带宽占用，又可以真正实现细节的隐藏。<br /><br />所以，封装对于 javascript 来说，是非常有用的！<br /><br />那么在 javascript 实现继承是为了什么呢？<br /><br />2.2 为什么要继承<br />在其它面向对象程序设计语言中，继承除了可以减少重复代码的编写外，最大的用处就是为了实现多态。尤其是在强类型语言中，尤为如此：<br /><br />1、在强类型语言中，一个变量不能够被赋予不同类型的两个值，除非这两种类型与这个变量的类型是相容的，而这个相容的关系就是由继承来实现的。<br /><br />2、在强类型语言中，对一个已有的类型无法直接进行方法的扩充和改写，要扩充一个类型，唯一的方法就是继承它，在它的子类中进行扩充和改写。<br /><br />因此，对于强类型的面向对象语言，多态的实现是依赖于继承的实现的。<br /><br />而对于 javascript 语言来说，继承对于实现多态则显得不那么重要：<br /><br />1、在 javascript 语言中，一个变量可以被赋予任何类型的值，且可以用同样的方式调用任何类型的对象上的同名方法。<br /><br />2、在 javascript 语言中，可以对已有的类型通过原型直接进行方法的扩充和改写。<br /><br />所以，在 javascript 中，继承的主要作用就是为了减少重复代码的编写。<br /><br />接下来我们要谈的两种实现继承的方法可能大家已经都很熟悉了，一种是原型继承法，一种是调用继承法，这两种方法都不会产生副作用。我们主要讨论的是这两种方法的本质和需要注意的地方。<br /><br />2.3 原型继承法<br />在 javascript 中，每一个类（函数）都有一个原型，该原型上的成员在该类实例化时，会传给该类的实例化对象。实例化的对象上没有原型，但是它可以作为另一个类（函数）的原型，当以该对象为原型的类实例化时，该对象上的成员就会传给以它为原型的类的实例化对象上。这就是原型继承的本质。<br /><br />原型继承也是 javascript 中许多原生对象所使用的继承方法。<br /><br /><pre name="code" class="java">function parentClass() {
    // private field
    var x = "I'm a parentClass field!";
    // private method
    function method1() {
        alert(x);
        alert("I'm a parentClass method!");
    }
    // public field
    this.x = "I'm a parentClass object field!";
    // public method
    this.method1 = function() {
        alert(x);
        alert(this.x);
        method1();
    }
}
parentClass.prototype.method = function () {
    alert("I'm a parentClass prototype method!");
}
parentClass.staticMethod = function () {
    alert("I'm a parentClass static method!");
}
 
function subClass() {
    // private field
    var x = "I'm a subClass field!";
    // private method
    function method2() {
        alert(x);
        alert("I'm a subClass method!");
    }
    // public field
    this.x = "I'm a subClass object field!";
    // public method
    this.method2 = function() {
        alert(x);
        alert(this.x);
        method2();
    }
    this.method3 = function() {
        method1();
    }
}
 
// inherit
subClass.prototype = new parentClass();
subClass.prototype.constructor = subClass;
 
// test
var o = new subClass();
 
alert(o instanceof parentClass);    // true
alert(o instanceof subClass);       // true
 
alert(o.constructor);  // function subClass() {...}
 
o.method1();    // I'm a parentClass field!
                // I'm a subClass object field!
                // I'm a parentClass field!
                // I'm a parentClass method!
o.method2();    // I'm a subClass field!
                // I'm a subClass object field!
                // I'm a subClass field!
                // I'm a subClass method!
o.method();     // I'm a parentClass prototype method!
 
o.method3();               // Error!!!
subClass.staticMethod();   // Error!!!</pre><br /><br />上面这个例子很好的反映出了如何利用原型继承法来实现继承。<br /><br />利用原型继承的关键有两步操作：<br /><br />首先创建一个父类的实例化对象，然后将该对象赋给子类的 prototype 属性。<br /><br />这样，父类中的所有公有实例成员都会被子类继承。并且用 instanceof 运算符判断时，子类的实例化对象既属于子类，也属于父类。<br /><br />然后将子类本身赋值给它的 prototype 的 constructor 属性。（注意：这里赋值的时候是没有 () 的！）<br /><br />这一步是为了保证在查看子类的实例化对象的 constructor 属性时，看到的是子类的定义，而不是其父类的定义。<br /><br />接下来，通过对 o.method1() 调用的结果我们会看到，子类继承来的公有实例方法中，如果调用了私有实例字段或者私有实例方法，则所调用的这些私有实例成员是属于父类的。<br /><br />同样，通过对 o.method2() 调用的结果我们看到，子类中定义的实例方法，如果调用了私有实例字段或者私有实例方法，则所调用的这些私有实例成员是属于子类的。<br /><br />通过对 o.method() 调用的结果我们看到，定义在父类原型上的方法，会被子类继承。<br /><br />通过对 o.method3() 调用的结果我们看到，子类中定义的实例方法是不能访问父类中定义的私有实例成员的。<br /><br />最后，通过对 subClass.staticMethod() 调用的结果我们看到，静态成员是不会被继承的。<br /><br />2.4 调用继承法<br />调用继承的本质是，在子类的构造器中，让父类的构造器方法在子类的执行上下文上执行，父类构造器方法上所有通过 this 方式操作的内容实际上都都是操作的子类的实例化对象上的内容。因此，这种做法仅仅为了减少重复代码的编写。<br /><pre name="code" class="java">
function parentClass() {
    // private field
    var x = "I'm a parentClass field!";
    // private method
    function method1() {
        alert(x);
        alert("I'm a parentClass method!");
    }
    // public field
    this.x = "I'm a parentClass object field!";
    // public method
    this.method1 = function() {
        alert(x);
        alert(this.x);
        method1();
    }
}
parentClass.prototype.method = function () {
    alert("I'm a parentClass prototype method!");
}
 
parentClass.staticMethod = function () {
    alert("I'm a parentClass stati