Components.Constructor 编辑
Summary
Creates a JavaScript function which can be used to create or construct new instances of XPCOM components.
Syntax
var func = [ new ] Components.Constructor(contractID [, interfaceName [, initializer ] ]);
Parameters
contractID
- A string containing the contract ID of the component
interfaceName
- If given,
nsISupports.QueryInterface()
will be called on each newly-created instance with the interface named by this string initializer
- If given, a string containing the name of a function which will be called on the newly-created instance, using the arguments provided to the created function when called
Description
Components.Constructor()
is a handy shortcut for creating instances of XPCOM components. It eliminates the clutter of typing Components.classes
, Components.interfaces
, createInstance
, and so on every time you wish to create an instance. It also gives creation of XPCOM objects more JavaScript-like syntax. Another important benefit is that it precomputes some of the computation it does, so using a function returned from Components.Constructor()
to create XPCOM objects is faster than creating the object from base principles, as demonstrated below. (This benefit is also partly a result of having to travel through the layer between the JavaScript engine and XPCOM fewer times.)
The behavior of functions returned by Components.Constructor()
varies depending upon the arguments given to Components.Constructor()
when called. If only one argument is given, that argument is the contract ID of the XPCOM component to create. The component is then returned immediately, with only the base interface nsISupports
available on it; you must call nsISupports.QueryInterface()
on it to call methods on the object. For example:
var BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1");
var bis = new BinaryInputStream();
print(bis.toString()); // "[xpconnect wrapped nsISupports]"
try
{
// someInputStream is an existing nsIInputStream
// throws because bis hasn't been QI'd to nsIBinaryInputStream
bis.setInputStream(someInputStream);
}
catch (e)
{
bis.QueryInterface(Components.interfaces.nsIBinaryInputStream);
bis.setInputStream(someInputStream); // succeeds now
}
If two arguments are given, the created instance will be nsISupports.QueryInterface()
'd to the XPCOM interface whose name is the second argument:
var BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream");
var bis = new BinaryInputStream();
print(bis.toString()); // "[xpconnect wrapped nsIBinaryInputStream]"
// someInputStream is an existing nsIInputStream
bis.setInputStream(someInputStream); // succeeds
If three arguments are given, then in addition to being nsISupports.QueryInterface()
'd, the instance will also have had an initialization method called on it. The arguments used with the initialization method are the arguments passed to the Components.Constructor()
-created function when called:
var BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream");
try
{
// throws, because number of arguments isn't equal to the number of
// arguments nsIBinaryInputStream.setInputStream takes
var bis = new BinaryInputStream();
}
catch (e)
{
// someInputStream is an existing nsIInputStream
bis = new BinaryInputStream(someInputStream); // succeeds
var bytes = bis.readByteArray(someNumberOfBytes); // succeeds
}
Compare instance creation from base principles with instance creation using Components.Constructor()
; the latter is much easier to read than the former (particularly if you're creating instances of a component in many different places):
var bis = Components.classes["@mozilla.org/binaryinputstream;1"]
.createInstance(Components.interfaces.nsIBinaryInputStream);
bis.setInputStream(someInputStream);
// assumes BinaryInputStream was initialized previously
var bis = new BinaryInputStream(someInputStream);
Components.Constructor()
is purely syntactic sugar (albeit speedy and pretty syntactic sugar) for actions that can be accomplished using other common methods. It is equivalent to the following JavaScript function:
function Components_Constructor(contractID, interfaceName, initializer)
{
var ccArgs = arguments;
function ctor()
{
var instance = Components.classes[contractID]
.createInstance(Components.interfaces.nsISupports);
if (ccArgs.length > 1)
{
instance.QueryInterface(Components.interfaces[interfaceName]);
if (ccArgs.length > 2)
instance[initializer].apply(instance, arguments);
}
return instance;
}
return ctor;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论