为什么在创建作用域时将参数传递给anon函数

Why passing parameters to anon function when creating scoping

本文关键字:参数传递 anon 函数 创建 作用域 为什么      更新时间:2023-09-26

对不起,标题很烂,但我想不出更好的了。

Polymer中的ShadowDOM.js文件是这样做的:

(function(scope) {
  "use strict";
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrap = scope.wrap;
  var nonEnumDescriptor = {
    enumerable: false
  };
  function nonEnum(obj, prop) {
    Object.defineProperty(obj, prop, nonEnumDescriptor);
  }
  function NodeList() {
    this.length = 0;
    nonEnum(this, "length");
  }
  NodeList.prototype = {
    item: function(index) {
      return this[index];
    }
  };
  nonEnum(NodeList.prototype, "item");
  function wrapNodeList(list) {
    if (list == null) return list;
    var wrapperList = new NodeList();
    for (var i = 0, length = list.length; i < length; i++) {
      wrapperList[i] = wrap(list[i]);
    }
    wrapperList.length = length;
    return wrapperList;
  }
  function addWrapNodeListMethod(wrapperConstructor, name) {
    wrapperConstructor.prototype[name] = function() {
      return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
    };
  }
  scope.wrappers.NodeList = NodeList;
  scope.addWrapNodeListMethod = addWrapNodeListMethod;
  scope.wrapNodeList = wrapNodeList;
})(window.ShadowDOMPolyfill);

简单的问题:为什么要传递参数window.ShadowDOMPolyfill

是的,这是一个可以直接执行的匿名函数。是的,所有的变量都将保持在函数内,避免污染。是的,scope将与window.ShadowDOMPolyfill相同。

这是我见过很多次的模式。我完全理解为什么不用变量等污染全局范围是好的。但是,为什么要通过窗口。是否将阴影DOMPolyfill作为第一个参数?据我所知,Window对象在函数中完全可用。。。那么上面的代码和之间有什么区别

(function() {
  "use strict";
  var scope = window.ShadowDOMPolyfill;
  ...
})();

在参数列表中定义函数所需的参数以完成分配给它的工作被认为是一种很好的做法。

虽然完全可以按照您建议的方式进行,但这会鼓励API撒谎,因为您无法查看函数签名并理解函数中包含的内容。

在这个特定的实例中,这两个示例在功能上是相同的,但是,假设有更多的参数,并且它们的用法和定义分散在函数体中。

(function(oneThing, anotherThing, aThirdThing) {
  ...
})(window.oneThing, window.anotherThing, window.aThirdThing);

比更可读

(function() {
  ... // with your vars somewhere inside.
})();

在您的示例中,您必须与开发人员强制执行一个约定,始终将这些定义放在首位,以保持可读性。然而,语言已经帮助您通过参数列表来强制执行这一点。

另一个可能的原因是它使测试更容易,并且与其他环境更兼容。Angular有一种类似的方法,他们建议使用变量$window而不是window,尽管它们具有相同的值。

一个简单的例子:

function myFunction(globalContext) {
   //adding stuff to the global object
}
myFunction(window || myGlobalObject)

此函数可以在Nodejs、Rhino或Nashorn引擎(而非浏览器环境)中接收参数windowmocked window或完全不同的全局对象