对不起,标题很糟糕,但我想不出更好的一个。
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
相同。
这是我见过很多次的模式。我完全理解为什么不用变量等污染全局范围是好的。但是,为什么将window.ShadowDOMPolyfill作为第一个参数传递?据我所知,Window对象在函数内完全可用...所以上面的代码之间有什么区别:
(function() {
"use strict";
var scope = window.ShadowDOMPolyfill;
...
})();
...
答案 0 :(得分:4)
在参数列表中定义您的函数所需的参数以便完成它所分配的工作,这被认为是一种很好的做法。
尽管按照您提出的方式完成此操作是完全可能的,但它鼓励使用撒谎的API ,从某种意义上说,您无法查看函数签名并了解进入功能。
在这个特定实例中,这两个示例在功能上是相同的,但是,想象有更多参数,它们的用法和定义分散在函数体中。
(function(oneThing, anotherThing, aThirdThing) {
...
})(window.oneThing, window.anotherThing, window.aThirdThing);
比
更具可读性(function() {
... // with your vars somewhere inside.
})();
在您的示例中,您必须与开发人员一起强制执行约定,以始终将这些定义放在顶部,以保持可读性。但是,语言已经可以帮助您使用参数列表强制执行该操作。
答案 1 :(得分:2)
另一个可能的原因是它使测试更容易,并且与其他环境更兼容。 Angular有一个类似的方法,因为他们建议使用变量$ window而不是window,尽管它们具有相同的值。
一个简单的例子:
function myFunction(globalContext) {
//adding stuff to the global object
}
myFunction(window || myGlobalObject)
此函数可以在Nodejs,Rhino或Nashorn引擎(不是浏览器环境)中作为参数window
,mocked window
或完全不同的全局对象接收