<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>随网之舞命名空间</title>
	<atom:link href="http://dancewithnet.com/tag/%e5%91%bd%e5%90%8d%e7%a9%ba%e9%97%b4/feed/" rel="self" type="application/rss+xml" />
	<link>http://dancewithnet.com</link>
	<description>WEB Design{HTML:CSS:Javascript:DOM:AJAX:PHP:Usability}/Viewpoint/Photo/Food/Mood</description>
	<lastBuildDate>Mon, 18 Jul 2011 02:45:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Javascript的一种模块模式</title>
		<link>http://dancewithnet.com/2007/12/04/a-javascript-module-pattern/</link>
		<comments>http://dancewithnet.com/2007/12/04/a-javascript-module-pattern/#comments</comments>
		<pubDate>Mon, 03 Dec 2007 16:49:07 +0000</pubDate>
		<dc:creator>秦歌</dc:creator>
				<category><![CDATA[Javascript & DOM & AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[命名空间]]></category>

		<guid isPermaLink="false">http://dancewithnet.com/2007/12/04/a-javascript-module-pattern/</guid>
		<description><![CDATA[全局变量是魔鬼。在YUI中，我们仅用两个全局变量：YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员作用域内的变量。我们建议在你的应用程序也使用类似的规则。
Douglas Crockfo... ]]></description>
			<content:encoded><![CDATA[<p><a href="http://yuiblog.com/blog/2006/06/01/global-domination/">全局变量是魔鬼。</a>在YUI中，我们仅用两个全局变量：YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员作用域内的变量。我们建议在你的应用程序也使用类似的规则。</p>
<p>Douglas Crockford已经传授了一个有用的单例模式（singleton pattern）实现此规则，我认为他的模式有益于你基于YUI的那些应用。Douglas叫它模块模式（module pattern）。它是如下工作的：<span id="more-1222"></span></p>
<ol>
<li>创建一个命名空间对象：如果你使用YUI，可以用YAHOO.namespace()方法：<code>    YAHOO.namespace("myProject");</code>这分配了一个空的myProject对象，是YAHOO的一个成员（如    果myProject已存在的话，则不会被覆盖）。现在我们可以开始添加YAHOO.myProject的成员。
</li>
<li>对你的命名空间对象分配一个匿名函数返回值：
<pre><code>YAHOO.myProject.myModule = function () {
return  {
  myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty被访问。";
  myPublicMethod: function () {
    YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod被访问。");
  }
};
}();<span> // 这个括号导致匿名函数被执行且返回</span>
</code></pre>
<p>注意有闭合大括号和紧接着的括号()的最后一行&#8212;这种符号导致了匿名函数的立即执行，返回包含myPublicProperty和myPublicMethod的对象。只要这个匿名函数一返回，返回对象就作为YAHOO.myProject.myModule被访问。</li>
<li>在匿名函数中，在返回语句前加入“私有”方法和变量。到目前为止，我们只是将myPublicProperty和myPublicMethod直接分配到YAHOO.myProject.myModule中。此外，当我们在返回语句之前放置一些代码时，这个模式还支持被增加的效用。
<pre><code>YAHOO.myProject.myModule = function () {
<span>//“私有”变量：</span>
var myPrivateVar = "我仅能在YAHOO.myProject.myModule内被访问。";
<span>//私有方法：</span>
var myPrivateMethod = function () {
    YAHOO.log("我仅能在YAHOO.myProject.myModule内被访问。");
}

return  {
    myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty能被访问。"
    myPublicMethod: function () {
    YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod能被访问。");
    <span>//在myProject,我能访问私有的变量和方法</span>
    YAHOO.log(myPrivateVar);
    YAHOO.log(myPrivateMethod());
    <span>//myPublicMethod的原生作用域是myProject，我们可以用“this”来访问公共成员。</span>
    YAHOO.log(this.myPublicProperty);
    }
};
}();</code></pre>
<p>在上面的代码中，我们从一个匿名函数返回有两个成员的一个对象。在YAHOO.myProject.myModule内部，可以分别用this.myPublicProperty和this.myPublicMethod来访问。在YAHOO.myProject.myModule外部，公共成员可以用YAHOO.myProject.myModule.myPublicProperty和YAHOO.myProject.myModule.myPublicMethod来访问。<br />私有变量myPrivateProperty和myPrivateMethod只能被匿名函数本身或返回对象的成员访问。尽管匿名函数会立即执行和终止，但它们依然是保留着，凭借闭包（closure）的力量——通过一个函数的局部变量在这个函数返回后是保留的规则。只要 YAHOO.myProject.myModule需要它们，我们的两个私有变量就不会被销毁。</li>
<li>实践这个模式。让我们来看看这个模式的一个常见应用案例。假设你有一个列表，列表上的一些项可以被拖拽。应用拖拽的项上有拖拽的CSS类。
<pre><code>&lt;!--这个脚本文件包含所有的YUI实用程序--&gt;
  &lt;script type=&quot;text/javascript&quot;
src=&quot;http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js&quot;&gt;&lt;/script&gt;
&lt;ul id=&quot;myList&quot;&gt;
   &lt;li class=&quot;draggable&quot;&gt;一项&lt;/li&gt;
   &lt;li&gt;二项&lt;/li&gt; &lt;!--二项将不能被拖拽--&gt;
   &lt;li class=&quot;draggable&quot;&gt;三项&lt;/li&gt;
   &lt;/ul&gt;
&lt;script&gt;
  YAHOO.namespace(&quot;myProject&quot;);
  YAHOO.myProject.myModule = function () {
 <span>//YUI实用程序的私有简写引用：</span>
  var yue = YAHOO.util.Event,
  yud = YAHOO.util.Dom;
 <span>//私有方法</span>
  var getListItems = function () {
 <span>// 注意这个地方使用其他的私有变量，包括&quot;yud&quot;YAHOO.util.Dom的简写：</span>
  var elList = yud.get(&quot;myList&quot;);
  var aListItems = yud.getElementsByClassName(
  &quot;draggable&quot;, <span>//得到仅有CSS类&quot;draggable&quot;的项</span>
  &quot;li&quot;, <span>//仅返回列表项</span>
  elList <span>//限定搜索改元素的子</span>
  );
  return aListItems;
  };
 <span>//这个放回的对象将变成YAHOO.myProject.myModule:</span>
  return  {
 aDragObjects: [], <span>//可对外访问的，存储DD对象</span>
 init: function () {
  <span>//直到DOM完全加载好，才实现列表项可拖拽：</span>
  yue.onDOMReady(this.makeLIsDraggable, this, true);
  },
 makeLIsDraggable: function () {
  var aListItems = getListItems(); <span>//我们可以拖拽的那些元素</span>
  for (var i=0, j=aListItems.length; i&lt;j; i++) {
  this.aDragObjects.push(new YAHOO.util.DD(aListItems[i]));
  }
  }
 };
  }();
<span>//上面的代码已经执行，所以我们能立即访问init方法：</span>
  YAHOO.myProject.myModule.init();
  &lt;/script&gt;</code></pre>
<p>这是一个简单的例子，特意写的详细一些——如果按照这种方式做，我们无疑能把它写的更紧凑。当项目变得更加复杂和它的API增加，这个模式缩放的很好。通过这种方式，它避免了全局命名空间，提供了对外的可以访问的API方法，支持受保护或“私有”的数据和方法。</li>
</ol>
<ul class="refer">
<li>[1]原文：<a href="http://yuiblog.com/blog/2007/06/12/module-pattern/">《a javascript module pattern》</a>。这是在YUI blog上的，有的地方可能打不开，可以搜一下英文的转载或者利用搜索引擎的缓存也能看。
<li>
<li>[2]<a href="http://www.javaeye.com/topic/93650">《A JavaScript Module Pattern &#8211; JavaScript的一种模组模式》</a>这是别人的翻译，参考了不少，不过感觉挺不方便看的，这是我翻译的这篇文章的一个原因，当然最主要的原因是这篇文章算是学习YUI的最基础的文章了，整个YUI的模块模式都基于此。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://dancewithnet.com/2007/12/04/a-javascript-module-pattern/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>

