2016-05-03 1 views
6

Извините, название отстой, но я не мог придумать лучшего.Зачем передавать параметры функции анона при создании области обзора

Файл ShadowDOM.js в Polymer делает это:

(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; 
    ... 
})(); 

...?

+1

мое предположение: личное предпочтение. – Jamiec

+1

Очиститель API. Возможно, крошечный рост производительности. Но функционально говоря, они оба делают то же самое. –

+0

Вау ... Я этого не ожидал. Я серьезно ожидал, что я пропустил некоторые огромные части Javascript, хотя я написал много кода (это было бы не в первый раз!) – Merc

ответ

4

Считается хорошей практикой определять параметры, необходимые вашей функции, чтобы выполнять работу, которую она назначила, в списке аргументов.

Хотя это вполне возможно сделать так, как вы предлагаете, оно поощряет API , в некотором смысле, что вы не можете смотреть на подпись функции и понимать, что входит в эту функцию.

В данном случае пример, два примера идентичны по функциональности, однако представьте, что существует больше параметров, а их определения и определения разбросаны по всему телу функции.

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

более читабельным, чем

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

В вашем примере, вы должны обеспечить соблюдение конвенции с вашими разработчиками всегда ставить эти определения в верхней части, чтобы сохранить читаемость. Тем не менее, язык уже помогает вам выполнить это с помощью списка аргументов.

+0

Мне очень нравится эта перспектива. –

+0

Это также лучше подходит для ответа на полный вопрос (чем мой был). –

2

Другая возможная причина заключается в том, что он упрощает тестирование и более совместим с другими средами. Угловое имеет аналогичный подход, поскольку они рекомендуют использовать переменную $ window вместо окна, хотя они имеют одинаковое значение.

Простой пример:

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

myFunction(window || myGlobalObject) 

Эта функция может принимать в качестве параметра window, а mocked window, или совершенно другой глобальный объект в двигателях Nodejs, Rhino или Насхорн (не браузер сред)

Смежные вопросы