diff options
Diffstat (limited to 'files/zh-cn/mozilla/javascript_code_modules/using/index.html')
-rw-r--r-- | files/zh-cn/mozilla/javascript_code_modules/using/index.html | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/files/zh-cn/mozilla/javascript_code_modules/using/index.html b/files/zh-cn/mozilla/javascript_code_modules/using/index.html deleted file mode 100644 index 41fdf9970e..0000000000 --- a/files/zh-cn/mozilla/javascript_code_modules/using/index.html +++ /dev/null @@ -1,194 +0,0 @@ ---- -title: 使用 JavaScript 代码 modules 模式 -slug: Mozilla/JavaScript_code_modules/Using -tags: - - Add-ons - - Extensions - - Guide - - JavaScript - - XPCOM -translation_of: Mozilla/JavaScript_code_modules/Using ---- -<p>{{ gecko_minversion_header("1.9") }}</p> - -<p>JavaScript code modules 在Gecko1.9中引入并被用于具备不同权限的作用域之间的代码共享。 Modules 也可以用于创建全局js单例,这在之前是通过使用XPCOM(跨平台组件模型)实现的。一个 JavaScript code module 是仅仅是位于注册位置的一些 JavaScript 代码。Module 被载入特定的js域,比如 XUL script or JavaScript XPCOM script, 通过<code><a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import()</a></code> or <code><a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils["import"]()</a></code>.</p> - -<h2 id="创建_JavaScript_code_module">创建 JavaScript code module</h2> - -<p>一个简单的例子my_module.jsm:</p> - -<pre class="brush: js notranslate" style="width: 900px;">var EXPORTED_SYMBOLS = ["foo", "bar"]; - -function foo() { - return "foo"; -} - -var bar = { - name : "bar", - size : 3 -}; - -var dummy = "dummy"; -</pre> - -<p>可以看到 module 使用规范的js语言来创建函数,对象,常量以及其他的数据类型。 Module 还定义了一个名为 <code>EXPORTED_SYMBOLS 的特殊数组,这个数组中的每一项都会被输出到声明中并且被注入到引入的作用域中。例如:</code></p> - -<pre class="brush: js notranslate">Components.utils.import("resource://app/my_module.jsm"); - -alert(foo()); // displays "foo" -alert(bar.size + 3); // displays "6" -alert(dummy); // displays "dummy is not defined" because 'dummy' was not exported from the module -</pre> - -<div class="note"><strong>Note:</strong> When you're testing changes to a code module, be sure to change the application's build ID (e.g. the version) before your next test run; otherwise, you may find yourself running the previous version of your code module's code still.</div> - -<h3 id="The_URL_for_a_code_module">The URL for a code module</h3> - -<p>正如你在上例中看到的, 你需要一个 URL 来导入一个代码块 (code module)。 (就像例子中的 "<a class="external" rel="freelink">resource://app/my_module.jsm</a>".)</p> - -<p>有三种模式的URL可供选择: <strong>chrome:……</strong>({{ gecko_minversion_inline("2") }}), <strong>resource:……</strong>, 或者 <strong>file:……</strong>.</p> - -<ul> - <li>如果你在为 Firefox 4 写一个扩展并且已经有了一个 <a href="/en/Chrome_Registration" title="en/Chrome registration">chrome.manifest</a>(里面是内容指示), 你可以将代码块 code module 放入你的内容文件夹并通过<code>chrome://<yourextension>/content/<yourmodule>.jsm指向它。</code></li> - <li>如果你的扩展或应用需要支持 Mozilla 1.9.x (Firefox 3.x), 你需要注册一个新的资源URL. 具体细节在这: <a href="#resource-urls">"Extending resource: URLs" section</a> .</li> -</ul> - -<h3 id="通过code_modules共享对象">通过code modules共享对象</h3> - -<p><code><a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import()</a></code> 的一个非常重要行为就是 module 加载后会被缓存起来, 并且随后的的导入不会重新加载一个新版的module, 而是使用之前缓存的版本。这就意味着当导入 module 多次时, 一个给定的 module 会被共享多次。只要引入某个module,任何对数据,对象和函数的变化都会体现在不同的引入该module的域中。比如,一个简单的module被引入到两个不同的域中,在其中一个域中做改变,另一个域也共享这种改变。如下例 :</p> - -<p>Scope 1:</p> - -<pre class="brush: js notranslate">Components.utils.import("resource://app/my_module.jsm"); - -alert(bar.size + 3); // displays "6" - -bar.size = 10; -</pre> - -<p>Scope 2:</p> - -<pre class="brush: js notranslate">Components.utils.import("resource://app/my_module.jsm"); - -alert(foo()); // displays "foo" -alert(bar.size + 3); // displays "13" -</pre> - -<p>这种共享行为可以被用来创建单例对象(singleton objects)并且可以被 跨windows 和 XUL script 和 XPCOM 组件所共享。</p> - -<p>注意:引入某个module的域获得了一组该module中定义的输出符号的按值复制的副本( by-value copy )。 对这些输出符号的改变或者重新定义不会传播到其他的域中。 (虽然对象的属性会通过引用来改变。)。例子如下:</p> - -<p>Scope 1:</p> - -<pre class="brush: js notranslate">Components.utils.import("resource://app/my_module.jsm"); - -bar = "foo"; -alert(bar); // displays "foo" -</pre> - -<p>Scope 2:</p> - -<pre class="brush: js notranslate">Components.utils.import("resource://app/my_module.jsm"); - -alert(bar); // displays "[object Object]" -</pre> - -<p>按值复制的主要效果就是简单类型的全局变量不会在不同的域之间共享。所以我们经常将变量放在大括号中,然后以对象的形式输出 (就像上例中的bar)。</p> - -<p>{{ h2_gecko_minversion("Unloading code modules", "7.0") }}</p> - -<p><code><a href="/en/Components.utils.unload" title="en/Components.utils.unload">Components.utils.unload()</a></code> 允许你卸载之前引入的module。该方法被调用后, 指向该module的引用可以继续工作,但是后续对该module的引入,就会重新加载并重新分配指向该module的引用值。</p> - -<h2 id="Extending_resource_URLs">Extending resource: URLs</h2> - -<p>{{ Gecko("2.0") }}之前,加载code module最常用的方式是—— <strong>resource:</strong> URLs. Resource URL 的基本语法如下:</p> - -<pre class="eval notranslate">resource://<alias>/<relative-path>/<file.js|jsm> -</pre> - -<p><code><alias></code> 是某个位置的别称,通常是一个相对于应用程序或者 XUL runtime的物理位置。这是一些由XUL runtime设置的预定义的别称:</p> - -<ul> - <li><code>app</code> - XUL application 位置的别名</li> - <li><code>gre</code> - XUL runtime 位置的别名</li> -</ul> - -<p><code><relative-path></code> 可以是多层的,经常是相对于alias的位置。最常见的相对路径是 "modules" 并常常被XUL Runner and Firefox使用. Code modules 是简单的js文件以 .js or .jsm 作为后缀。</p> - -<p><code><alias></code> 对于你的插件必须是唯一的,因为应用和其他的扩展共享同样的命名空间对所有的别称。</p> - -<h3 id="使用chrome.manifest">使用chrome.manifest</h3> - -<p>The easiest way for extensions and XUL applications to add custom aliases is by registering an alias in the <a href="/en/Chrome_Registration" title="en/Chrome_Registration">chrome manifest</a> using a line like this:</p> - -<pre class="eval notranslate">resource <em>aliasname</em> <em>uri/to/files/</em> -</pre> - -<p>For example, if the XPI for your <em>foo</em> extension includes a top-level modules/ directory containing the <em>bar.js</em> module (that is, the modules/ directory is a sibling to chrome.manifest and install.rdf), you could create an alias to that directory via the instruction:</p> - -<pre class="eval notranslate">resource foo modules/ -</pre> - -<p>(Don't forget the trailing slash!) You could then import the module into your JavaScript code via the statement:</p> - -<pre class="brush: js notranslate">Components.utils.import("resource://foo/bar.js"); -</pre> - -<h4 id="Programmatically_adding_aliases">Programmatically adding aliases</h4> - -<p>Custom aliases to paths that can be represented as an {{ interface("nsILocalFile") }} can be programmatically added as well. For example:</p> - -<pre class="brush: js notranslate">// Import Services.jsm unless in a scope where it's already been imported -Components.utils.import("resource://gre/Services.jsm"); - -var resProt = Services.io.getProtocolHandler("resource") - .QueryInterface(Components.interfaces.nsIResProtocolHandler); - -var aliasFile = Components.classes["@mozilla.org/file/local;1"] - .createInstance(Components.interfaces.nsILocalFile); -aliasFile.initWithPath("/some/absolute/path"); - -var aliasURI = Services.io.newFileURI(aliasFile); -resProt.setSubstitution("myalias", aliasURI); - -// assuming the code modules are in the alias folder itself -</pre> - -<h2 id="Notes">Notes</h2> - -<h3 id="自定义_modules_和_XPCOM_components">自定义 modules 和 XPCOM components</h3> - -<p>Note that prior to {{ Gecko("2.0") }} JavaScript XPCOM components are loaded before chrome registration. This means you can't use <code><a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import()</a></code> with your own resource URL at the top level in a component source. A possible solution is moving the call to <code><a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import()</a></code> into the XPCOM component constructor (<a class="external" href="http://groups.google.com/group/mozilla.dev.apps.firefox/browse_thread/thread/e178d41afa2ccc87?hl=en#" title="http://groups.google.com/group/mozilla.dev.apps.firefox/browse_thread/thread/e178d41afa2ccc87?hl=en#">discussion</a>).</p> - -<h3 id="Packaging_notes">Packaging notes</h3> - -<p>It's important to note that you should not typically put your JavaScript code modules in a JAR file in your add-on. Firefox 3.6 doesn't support them at all, and there's only one case in which it's remotely useful: a Firefox 4-only add-on which must be installed unpacked. Otherwise placing code modules in a JAR file breaks compatibility unnecessarily.</p> - -<h2 id="Importing_CommonJS_modules">Importing CommonJS modules</h2> - -<p>The JavaScript code modules described here are not the same thing as <a href="http://www.commonjs.org/specs/modules/1.0/">CommonJS modules</a>, but you can import CommonJS modules into any scope where you can use <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.import">Components.utils.import</a>. Just call the following:</p> - -<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">const</span> <span class="punctuation token">{</span> require <span class="punctuation token">}</span> <span class="operator token">=</span> Cu<span class="punctuation token">.</span><span class="keyword token">import</span><span class="punctuation token">(</span><span class="string token">"resource://gre/modules/commonjs/toolkit/require.js"</span><span class="punctuation token">,</span> <span class="punctuation token">{</span><span class="punctuation token">}</span><span class="punctuation token">)</span></code></pre> - -<p>This will import <code>require()</code> into your scope.</p> - -<p>You can then use that to import CommonJS modules. You can import <a href="/en-US/docs/Mozilla/Add-ons/SDK">Add-on SDK</a> modules in just the same way you could from an SDK add-on:</p> - -<pre class="brush: js notranslate">// import the SDK's base64 module - -var base64 = require("sdk/base64"); -base64.encode("hello"); // "aGVsbG8="</pre> - -<p>You can import other CommonJS modules, too, as long as you know the path to them:</p> - -<pre class="brush: js notranslate">// import my module - -var myModule = require("resource://path/to/my/module.js");</pre> - -<p>In this case, though, you might be better off <a href="/en-US/Add-ons/SDK/Low-Level_APIs/_loader">creating your own loader</a>, so you can specify the <code><a href="/en-US/Add-ons/SDK/Low-Level_APIs/_loader#paths">paths</a></code> property yourself.</p> - -<h2 id="See_also" name="See_also">See also</h2> - -<ul> - <li><a href="/en-US/docs/Mozilla/JavaScript_code_modules">JavaScript code modules</a> topic page</li> -</ul> |