Глобальный импорт в JavaScript
Может кто-нибудь объяснить мне, что это делает в JavaScript?
(function (x,y){}(x,y));
или это
// global import
(function ($, YAHOO) {
// now have access to globals jQuery (as $) and YAHOO in this code
}(jQuery, YAHOO));
Я никогда не видел ничего подобного в других языках, таких как Java или C++
4 ответа
function(x, y) { }
является анонимной функцией.
(x, y)
вызывает эту функцию, передавая x
а также y
в качестве параметров.
Цель второго кодового блока состоит в том, чтобы сделать jQuery
доступно как $
(без определения $
глобально) и импортирование YAHOO
в локальной области, чтобы сделать поиск переменных немного быстрее.
Кроме того, он создает новую область видимости, поэтому любые переменные, определенные с var
внутри не будет глобальным.
Первый блок кода часто используется таким образом для создания новых переменных, например, когда вы находитесь в цикле и вам нужно создать переменную с текущим i
значение для обратного вызова:
for(var i = 0; i < 10; i++) {
(function(i) {
setTimeout(function() {
alert("number " + i);
}, 1000 * i);
})(i);
}
Без этой новой области вы бы имели то же самое i
каждый раз и таким образом предупредить "номер 10" 10 раз.
Первый вызывает анонимную функцию, которая принимает 2 аргумента и ничего не делает, с x
а также y
в качестве аргумента.
Второй делает то же самое. Он использует $ в качестве первого имени аргумента и передает jQuery в качестве значения аргумента. Таким образом, внутри этой функции можно использовать $
ссылаться на jQuery
объект. Это способ псевдонима переменных к другому имени внутри функции.
C# имеет похожую концепцию, называемую лямбда-выражением.
public static Func<int> Foo()
{
int a = 1,
b = 2;
return () => a + b;
}
Это универсальная функция первого класса (под функцией первого класса подразумевается, что возвращается сама функция, а не ее результат), которая объявляется анонимно.
В этом случае я также покажу вам то, что называется замыканием - возвращаемый метод заключает в себе "локальные" переменные a и b, что позволяет им сохраняться, когда Foo выходит из области видимости. Во многих языках анонимные методы реализуют замыкания.
Анонимные методы тоже действительно хороши - вы можете выполнить инъекцию поведения, как в этом методе тестирования:
public static TimeSpan BenchmarkMe(Action timeThis)
{
Stopwatch sw = Stopwatch.StartNew()
timeThis();
sw.Stop;
return sw.Elapsed;
}
Вы можете передать анонимную функцию, которая возвращает TimeSpan в этот метод, который выполнит тест для одного прохода против него. Отличная, а?