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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:108 次

字数:6503

最后编辑:8 年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文