这篇翻译不完整。请帮忙从英语翻译这篇文章。
Components.classes
是一个只读的对象,其属性值是由 ContractID 索引的。
简介
Components.classes
是一个只读的对象,它的属性实现了 nsIJSCID
接口。每个对象都表示了 XPCOM components 的一个 class, 而且这个 class 能够被重构或作为一个 XPCOM service 来访问。
该对象的属性是由 component class 的 ContractID 或 human-readable 可读的名称进行索引的。
All of the properties and methods of the nsIJSCID
以及其父接口 nsIJSID
的所有属性和方法对于使用该对象的对象都是有效的。
注意 Components.classes
反映了这些组件 classes 以及能够被预先安装并且由 component manager 使用 ContractIDs 预先注册上。如果你想要使用仅仅将 CID 注册的 class, 请使用 Components.classesByID
替换Components.classes
来进行获取。
Note also that it is possible that a given add-on component with a given ContractID will be present on one machine but not have been installed on another machine. If the given element in the Components.classes
object is not registered on the machine then trying to access it will generate a JavaScript warning in strict mode and the value returned will be the JavaScript value undefined
. You should use the in
operator to test for the element before trying to access it:
if (!("@some/bogus/class;1" in Components.classes)) // do something...
The properties of the Components.classes
object can be enumerated using a for...in
loop.
用法
为了能够检索到给定 ContractID 的对象,你可以按照下面的方式来查询Components.classes
array :
var clazz0 = Components.classes["@mozilla.org/messenger;1"];
clazz0
是针对 ContractID @mozilla.org/messenger;1
的 class 对象, 它通常不是由自己来使用的,但是该对象的 createInstance
和 getService
方法可用来创建 component 的一个新的实例或访问一个单例的实例,如果 contact ID 代表一种服务的话。
一个 新的 XPCOM component 实例 可以从通过返回的 class 对象来创建:
var obj = Components.classes["@mozilla.org/supports-array;1"] .createInstance(Components.interfaces.nsISupportsArray);
上面也可以简写成
var obj = Components.classes["@mozilla.org/supports-array;1"] .createInstance(); obj.QueryInterface(Components.interfaces.nsISupportsArray);
如果你不向 createInstance()
提供一个特定的接口, 它就会返回一个 针对Component 的 XPConnect wrapper, 它会仅暴露 nsISupports
interface 的方法 ( 在某些特定场合下,special wrappedJSObject property 也可以被使用).
To access a service (a singleton component, 要使用单例模式访问组件,就应该使用 getService
来替代 createInstance
:
var os = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService);
The first time anyone accesses a service, the corresponding component is created under the hood.
简化写法
实际操作时,一般会将 Components.classes
和 Components.interfaces
的引用存储成常量的形式:
const Cc = Components.classes, Ci = Components.interfaces; var os = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService);
A less known trick, useful when creating multiple instances of the same component, is to use the new
operator on the class object:
var clazz = Components.classes["@mozilla.org/supports-array;1"]; var inst = new clazz(Components.interfaces.nsISupportsArray);
This implicitly calls the createInstance()
method for you. You still have to provide the interface name each time you create an instance, which is not necessary when using Components.Constructor
.
Determining if a component has to be instantiated or used as a service
In the general case it is not possible to programmatically determine if a given component has to be instantiated or used as a service.
Often, this is stated in the documentation of the component you want to use. If this is not the case, you might want to try and find example usages of that component within MXR.