Cette traduction est incomplète. Aidez à traduire cet article depuis l'anglais.
Résumé
Crée une fonction JavaScript qui peut être utilisé pour construire de nouvelles instances de composants XPCOM.
Syntaxe
var func = [ new ] Components.Constructor(contractID [, interfaceName [, initializer ] ]);
Paramètres
contractID
- Une chaîne contenant l'ID du composant
interfaceName
- Si donné,
nsISupports.QueryInterface()
seront appelés à chaque instance nouvellement créée avec l'interface nommée par cette chaîne initializer
- Si donné, une chaîne contenant le nom d'une fonction qui sera appelée sur l'instance nouvellement créée, en utilisant les arguments fournis à la fonction créée lorsqu'il est appelé
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; }