Подтвердить что ты не робот

Зачем использовать (function() {}). Call (this);?

В последнее время я изучаю некоторые библиотеки JS, которые были написаны людьми, которые действительно знали, что они делают, и я продолжаю видеть этот шаблон, и я не могу найти информацию об этом. Я прочитал документы по методу .call(), но для меня это не имело смысла. Я надеюсь получить примеры из этих добрых старых классических углубленных SO-объяснений с примерами.

(function(undefined){
   /*(insert entire library here)*/
}).call(this);

Что это? Почему это хороший способ написать библиотеку?

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

4b9b3361

Ответ 1

Разберите этот фрагмент кода.

Во-первых, есть анонимная функция с непосредственным вызовом. Это похоже на это:

(function () {/**/}).call();
(new Date()).getTime(); // timestamp since 1970 jan 1 in milliseconds

Мы не присваиваем переменной new Date() переменной, вместо этого мы используем ее немедленно.


Теперь зачем использовать .call вместо ()?

.call - это метод, который есть у всех Functions. Первый аргумент - это то, что будет привязано this, последующие аргументы будут переданы как аргументы функции. Итак:

(function () {
    console.log(this.foo); // bar
}).call({ "foo": "bar" });

Это работает в сочетании с undefined (см. ниже).

.call совпадает с .apply с одним незначительным отличием. .apply принимает только 2 аргумента, где второй - массив аргументов. Это было бы похоже:

(function () {}).call(this, "foo", "bar");
(function () {}).apply(this, [ "foo", "bar" ]);

Общепринятое применение применяется в сочетании с магической переменной arguments.

(function () {
     console.log(Array.prototype.slice.call(arguments, 1)); // [ "bar" ]
})([ "foo", "bar" ]);

Array.prototype.slice.call(arguments, 1) может выглядеть страшно, но на самом деле это просто arguments.slice(1), но arguments не является Array, поэтому он не имеет функции slice. Мы используем функцию Array slice и используем .call для установки this в arguments. Array.prototype.slice(arguments, 1??) неверно.


Теперь, почему существует this в .call(this)? this всегда указывает на контекст, в котором вы находитесь. Если вы находитесь в экземпляре класса, он укажет на экземпляр, и если вы находитесь в глобальной области действия, это укажет на это. В среде браузера это также window.


Почему undefined? Поскольку мы сделали .call(this) без второго аргумента, все аргументы нашей анонимной функции undefined. Я не уверен, почему вам нужно сделать явную переменную с именем undefined. Возможно, это поддержка некоторых браузеров или какого-либо инструмента для линта, который любит видеть undefined.

Благодаря @TedHopp. undefined изменчив.

var undefined = "foo";
console.log(undefined); // undefined

(function (undefined) {
    console.log(undefined); // "foo"
})("foo");

Вы можете так же легко:

(function () {
    /* code here */
}());

Это абсолютно справедливо и работает одинаково. Для использования формы, которую вы опубликовали, могут быть некоторые преимущества производительности или линки.