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

Какова эта конструкция кода, которая обертывает части библиотеки и для чего она полезна?

Я подражал библиотеке и смог написать следующий код. Этот код создал объект 'c', которому назначена функция 'a'. Итак, чтобы позвонить 'a', мне придется писать c.a().

Кроме того, мне удалось добавить дополнительные функции к этому объекту 'c'. Я хочу понять, что происходит в этом коде. Он не похож на обычное объектно-ориентированное программирование. Что называется этим типом javascript-программирования?

var c = (function(c) {
    if (c === undefined) {
        c = {};
    }

    function a() {
        alert(1);
    }
    c.a = a;
    return c;
}(c));
4b9b3361

Ответ 1

Это шаблон модуля. Вы увидите много вариантов этого шаблона, поэтому важно понять, что на самом деле происходит, вы не можете просто имитировать его.

Точкой этого фрагмента кода является завершение объекта c (обычно это ваша глобальная библиотека). Вероятно, у вас есть много похожих фрагментов кода в вашем приложении, все куски c, возможно, каждый из них в своем собственном файле.

Если объект библиотеки c, который передается как аргумент функции, еще не существует (c === undefined), он создается. Это позволяет не зависеть от порядка выполнения или предзагрузочного файла.

Правильная часть задания - IIFE (выражение, вызываемое мгновенно вызывается) - это функция, которая немедленно вызывается. Преимущество этой конструкции состоит в том, что она создает область, в которой переменные (например, функция a) могут быть объявлены без загрязнения внешней (глобальной) области. Здесь точка является спорной, как a является экстернализирована но в любом случае модуль обычно зависит от нескольких внутренних (частных) функций и переменных.

Подробности, которые могут потребовать объяснения: все эти файлы выглядят так, как будто они определяют новую переменную c, но здесь нет проблем, даже если файлы объединены: операторы var не определяют новую переменную, если он уже существует (переменная определена для всей области, здесь глобально, еще до точки объявления).

Другим способом написать это было бы

var c = c || {}; // ensure the c variable is defined, and initialize its value it if necessary

(function() { // let use an IIFE to have a protected scope and not pollute the global one
  function a() {
    alert(1);
  }
  c.a = a; // let augment c
})();

Этот, вероятно, более ясный, поскольку

  • он явно разделяет два этапа (c инициализация и завершение c с использованием IIFE)
  • он не зависит от двух переменных c с тем же именем
  • он менее подробный

Ответ 2

Здесь тот же код с добавленными комментариями о том, что делает каждая строка, и что происходит, когда мы передаем его.

//Here, we're defining a function that will return an object.
//its only parameter is named 'c'
//this is confusing, since the parameter has the same name as the global definition of the function.

//the var c definition is the global definition. the function parameter is not.
//so every reference to anything named 'c' inside the function definition is local. 
var c = (function(c) 
{
  //if c (the c we passed as a parameter) is not yet defined
  if (c === undefined) {
    //define c as an object
    c = {};
  }

  //define a function
  function a() {
    alert(1);
  }
  //attach it to the object
  c.a = a;

  //return the object
  return c;
}(c)); // call the constructor we just defined, using the global definition of `c`.
       // the first time we pass this point, c as a variable is still undefined.

Ответ 3

var c = (function(c) {
    if (c === undefined) {
        c = {};
    }

    function a() {
        alert(1);
    }
    c.a = a;
    return c;
}(c));

Давайте сделаем это шаг за шагом.

var c =

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

( .... )

Это означает, что все, что внутри, должно рассматриваться как выражение.

function(c)

означает, что это "выражение" является функцией, которая принимает аргумент. Этот аргумент впредь будет называться именем c до тех пор, пока функция не будет закончена. Любая переменная с именем c, которая была объявлена ​​вне области функции, таким образом, была бы недоступна непосредственно здесь. Хотя, если он находится в глобальной области действия, а глобальная область видимости - это объект окна, его можно назвать window.c.

if (c === undefined) { ... }

проверяет, передан ли ему аргумент undefined или нет. Вернул бы true, если это undefined, и таким образом выполнит то, что когда-либо находится внутри блока if.

c = {}

установите переменную c в пустой объект. Итак, если аргумент был (прошел или) undefined, мы сами определяем его здесь (и определяем его на пустой объект....).

function a() { alert(1); }

объявлена ​​функция с именем a, вызывающим, который приведет к появлению цифры 1. Обратите внимание, что это просто объявление функции. Мы еще не вызвали функцию.

c.a = a

Аргументу c теперь присваивается свойство с именем a, которое относится к только что созданной функции a.

return c

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

(fun...}(c))

вызовите функцию, которую мы только что создали, и передаем ей в качестве аргумента текущее значение c. так как мы назвали функцию выражением, результатом этого выражения будет то, что является возвращаемым значением функции. И наша функция возвращает объект (который мы передали ему) после присвоения ему свойства.

Поскольку это выражение было приравнено к переменной c, возвращаемое значение выражения (которое является возвращаемым значением функции) теперь удерживается с переменной c.

Если вы прочтете все это правильно, вы должны знать, что переменная c теперь будет содержать объект, у которого будет свойство a, которое является функцией, которая предупреждает номер 1. И этот объект также сохраняет свойства это могло быть и раньше.

Если мы отключим этот код, чтобы сделать его читаемым, просто указав имена переменных:

var myObject = (function(someObject) {
    if (someObject === undefined) {
        someObject = {};
    }
    function alertOne () {
        alert(1);
    }
    someObject.alertOne = alertOne;
    return someObject;
}(myObject));

Это шоу является эпизодом из раскрывающего шаблона модуля, в котором говорится о том, как добавить дополнительные свойства к объекту, который был объявлен ранее, элегантно, без загрязнения глобальной области. Выпущенные сразу выраженные выражения функции (IIFE).

Ответ 4

Почему в конце мы написали (c)) снова?

Это называется немедленно вызывается функция.

(function(received argument){

     //some code here.......

})(passed argument)  //<-- here the function is invoked 

c - переданный аргумент. Эта функция вызывается сразу же после ее создания. Этот тип декларации используется для сохранения переменных private и для сохранения глобального пространства имен.

Шаблон в вашем коде используется для создания модулей.

............ Теперь перейдите к вашему коду:............

, если аргумент undefined:.............

Во-первых, ...}(c)) эта часть непосредственно вызываемой функции вызывается. Она передается с аргументом c, который еще не определен. (function(c){... часть принимает этот аргумент c.

Здесь сначала passed argument c есть undefined.So if(c==undefined) запускается. В этой точке с помощью оператора c={} undefined object c присваивается empty object.

Здесь function a() { //... } - это закрытый метод, созданный внутри модуля. Его невозможно получить глобально.

Частный метод a создан глобально доступен, назначив его с помощью инструкции c.a=a. Таким образом, когда объект вернется, вы можете вызвать этот метод на глобальный контекст.

Таким образом, новому созданному пустующему объекту c присваивается метод под названием a. Затем он возвращается и var c получает этот объект.

, если переданный аргумент не undefined:............

Но если passed c является not undefined, скажем, если объект передан, то новый объект не создается. Я имею в виду, если if(c==undefined) является фальшивым. Таким образом, он не выполняется. Я имею в виду, что новый пустой объект не является created.Then Прошедшему объекту присваивается новый метод под названием a с помощью c.a=a

Это просто.

Код ниже - это гораздо более простая версия вашего кода. Он автоматически отправит пустой объект, если он изначально был undefined. Так что вам не нужно беспокоиться о том, что это undefined или нет. Он называется увеличение.

var c = (function(c) {

    function a() {
        alert(1);
    }
    c.a = a;
    return c;
}(c || {} ));

Ответ 5

Эта статья, написанная Ben Cherry, помогла мне понять этот тип шаблона: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html

Выдержка из статьи:

Анонимные закрытия

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

(function () {
    // ... all vars and functions are in this scope only
    // still maintains access to all globals
}());

Обратите внимание на () вокруг анонимной функции. Это требуется для языка, поскольку утверждения, начинающиеся с функции токена, всегда считаются объявлениями функций. Включение () вместо этого создает выражение функции.

Глобальный импорт

JavaScript имеет функцию, известную как подразумеваемые глобальные переменные. Всякий раз, когда используется имя, интерпретатор перемещает цепочку областей назад, ища оператор var для этого имени. Если ни один не найден, эта переменная считается глобальной. Если он используется в присваивании, глобальный создается, если он еще не существует. Это означает, что использование или создание глобальных переменных в анонимном закрытии легко. К сожалению, это приводит к жесткому управлению кодом, поскольку его не очевидным (для человека), какие переменные глобальны в данном файле.

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

(function ($, YAHOO) {
    // now have access to globals jQuery (as $) and YAHOO in this code
}(jQuery, YAHOO));

Экспорт модуля

Иногда вы просто не хотите использовать глобальные переменные, но хотите их объявить. Мы можем легко сделать это, экспортируя их, используя возвращаемое значение анонимных функций. Это позволит заполнить базовый шаблон модуля, поэтому полный пример:

var MODULE = (function () {
    var my = {},
        privateVariable = 1;

    function privateMethod() {
        // ...
    }

    my.moduleProperty = 1;
    my.moduleMethod = function () {
        // ...
    };

    return my;
}());

Обратите внимание, что weve объявляет глобальный модуль с именем MODULE с двумя общедоступными свойствами: методом с именем MODULE.moduleMethod и переменной с именем MODULE.moduleProperty. Кроме того, он поддерживает частное внутреннее состояние, используя закрытие анонимной функции. Кроме того, мы можем легко импортировать необходимые глобалы, используя шаблон, который мы узнали выше

Ответ 6

Что вы делаете, объявляете анонимную функцию, а затем вызываете ее с параметром c и присваиваете ее переменной, также называемой c, что очень запутывает: -)

Переименование переменных - это то, что у вас есть:

var result=(function (input_parameter){...} (parameter_used_to_call_my_function));

Заключительный (c), о котором вы спрашиваете, это параметр для вызова функции. Легче видеть, используете ли вы более длинный синтаксис:

var my_function=function(input_parameter){...};
var result=my_function(result);

Также стоит отметить, что вы вызываете my_function с помощью result (хотя вы его назвали c) в качестве параметра, который также является именем только что созданной переменной, чтобы сохранить возвращаемое значение функция. JS соглашается с этим, потому что он не является строгим с тем, как вы обрабатываете переменные, но это путаный способ писать код. Вы объявляете переменную и передаете ее (переменная с этим именем, которая в этой точке не должна существовать) в качестве параметра вашей функции на всякий случай, когда она была объявлена ​​ранее (и заботясь об этом случае внутри функции, которая, по крайней мере, согласован).

Что происходит внутри my_function, так это то, что вы проверяете, имеет ли ваш параметр предыдущее значение (что я объяснил, если предыдущий абзац); если он был undefined, вы инициализируете его пустым объектом. Затем вы добавляете функцию a к input_parameter и возвращаете ее.

Я не знаю, есть ли название для этого типа программирования, но использование одного и того же имени переменной для разных вещей не выглядит хорошей идеей: -)