Если говорить просто, то замыкание - это внутренняя функция. Ведь javascript разрешает создавать функции по ходу выполнения скрипта. И эти функции имеют доступ к переменным внешней функции.
В этом примере создается внутренняя функция func, изнутри которой доступны как локальные переменные, так и переменные внешней функции outer:
function outer() {
var outerVar;
var func = function() {
var innerVar
...
x = innerVar + outerVar
}
return func
}
Когда заканчивает работать функция outer, внутренняя функция func остается жить, ее можно запускать в другом месте кода.
Получается, что при запуске func используется переменная уже отработавшей функции outer, т.е самим фактом своего существования, funcзамыкает на себя переменные внешней функции (а точнее - всех внешних функций).
Наиболее часто замыкания применяются для назначения функций-обработчиков событий:
function addHideHandler(sourceId, targetId) {
var sourceNode = document.getElementById(sourceId)
var handler = function() {
var targetNode = document.getElementById(targetId)
targetNode.style.display = ‘none’
}
sourceNode.onclick = handler
}
Эта функция принимает два ID элементов HTML и ставит первому элементу обработчик onclick, который прячет второй элемент.
Т.е,
// при клике на элемент с ID="clickToHide"
// будет спрятан элемент с ID="info"
addHideHandler("clickToHide", "info")
Здесь динамически созданный обработчик события handler использует targetId из внешней функции для доступа к элементу.
Каждое выполнение функции хранит все переменные в специальном объекте с кодовым именем [[scope]], который нельзя получить в явном виде, но он есть .
Каждый вызов var... - всего лишь создает новое свойство этого объекта, а любое упоминание переменной - первым делом ищется в свойствах этого объекта.
Такова внутренняя структура "области видимости" - это обыкновенный объект. Все изменения локальных переменных являются изменениями свойств этого неявного объекта.
Обычно после того, как функция закончила выполнение, ее область видимости [[scope]], т.е весь набор локальных переменных убивается.
Общий поток выполнения выглядит так:
// функция для примера
function sum(x,y) {
// неявно создался объект [[scope]]
...
// в [[scope]] записалось свойство z
var z
// нашли переменную в [[scope]], [[scope]].z = x+y
z = x+y
// нашли переменную в [[scope]], return [[scope]].z
return z
// функция закончилась,
// [[scope]] никому больше не нужен и умирает вместе с z
}
Кстати, для кода вне функции(и вообще глобальных переменных) роль объекта-контейнера [[scope]] выполняет объект window.
Когда одна функция создается внутри другой, то ей передается ссылка на объект с локальными переменными [[scope]] внешней функции.
Благодаря существованию этой ссылки, из внутренней функции можно получить переменные внешней функции - через ссылку на ее [[scope]]. Сначала ищем у себя, затем - во внешнем [[scope]] - и так далее по цепочке до самого объекта window.
Замыкание - это когда объект локальных переменных [[scope]] внешней функции остается жить после ее завершения.
Внутренняя функция может обратиться к нему в любой момент и получить переменную внешней функции.
Например, разберем работу функции, которая устанавливает обработчики событий:
function addHideHandler(sourceId, targetId) {
// создан объект [[scope]] со свойствами sourceId, targetId
// записать в [[scope]] свойство sourceNode
var sourceNode = document.getElementById(sourceId)
// записать в [[scope]] свойство handler
var handler = function() {
var targetNode = document.getElementById(targetId)
targetNode.style.display = ‘none’
}
sourceNode.onclick = handler
// функция закончила выполнение
// (***) и тут - самое интересное!
}
При запуске функции все происходит стандартно:
создается [[scope]]
туда записываются локальные переменные
внутренняя функция получает ссылку на [[scope]]
Но в самом конце - внутренняя функция присваивается sourceNode.onclick. Внешняя функция закончила свою работу, но внутренняя - может запуститься когда-нибудь потом.
Интерпретатор javascript не проводит анализ - понадобятся ли внутренней функции переменные из внешней, и какие переменные могут быть нужны.
Вместо этого он просто оставляет весь [[scope]] внешней функции в живых.
Чтобы когда внутренняя функция запустится, если она вдруг не найдет какую-либо переменную в своем [[scope]] - она могла обратиться к [[scope]] внешней функции и нашла бы ее там.
Если внешняя функция была создана внутри еще одной (еще более внешней) функции - то в цепочку добавляется еще один консервированный [[scope]] и так - до глобальной области window.
Функция addEvents принимает массив div'ов и ставит каждому вывод своего номера на onclick.
С вопроса "Почему это не работает?" люди обычно начинают изучение замыканий.
function addEvents(divs) {
for(var i=0; i<divs.length; i++) {
divs[i].innerHTML = i
divs[i].onclick = function() { alert(i) }
}
}
Для тестового примера сделаем 10 разноцветных нумерованных div'ов с разными цветами:
function makeDivs(parentId) {
for (var i=0;i<10;i++) {
var j = 9-i
var div = document.createElement('div')
div.style.backgroundColor = '#'+i+i+j+j+j+i
div.className="closure-div"
div.style.color = '#'+j+j+i+i+i+j
document.getElementById(parentId).appendChild(div)
}
}
Кнопка ниже создаст 10 дивов и вызовет для них addEvents
Если Вы покликаете на div'ы - они все выдают одинаковый alert.
Такой глюк возник из-за того, что все функции div[i].onclick получают значение i из одного на всех [[scope]] внешней функции. А это значение ([[scope]].i) на момент активации onclick-обработчика равно 10 (цикл завершился как только i==10).
Чтобы все было в порядке, в таких случаях применяют специальный прием - выделение [[scope]]. Следующая функция работает правильно. В ней все то же самое, кроме div.onclick.
Теперь все должно быть в порядке - каждый div дает alert на свой номер.
Для присваивания div.onclick запускается временная функция function(x) {..}, принимающая аргумент x и возвращающая обработчик, который берет x из [[scope]] этой временной функции.
Запись function(x) {..} используется для создания функции, и тут же (i) - для запуска с аргументом i.
Вообще, javascript очень удобный в этом смысле язык. Допускает любые конструкции, например, вместо последовательных вызовов:
var f = function(a) { return [0, a, 2*a] }
var t = f(1)
var result = t[2] // 2
можно в одну строчку создать и тут же вызвать функцию и тут же получить 2й элемент массива:
var result = function(a){ return [0,a,2*a] }(1)[2]
Временная функция function(x) {..} заканчивает работать тут же, оставляя в своем [[scope]] правильное значение x, равное текущей переменной i цикла.
Когда обработчик активизируется - alert возьмет из [[scope]] ближайшей внешней функциии правильное значение x.
По идее, этих примеров должно хватать для понимания и практического использования замыканий.
Речь идет просто об иерархии, в чем-то аналогичной наследованию через прототипы.
Однако, насколько я понимаю - из стандарта (http://javascript.ru/ecma/part10#a-10.1.4) не следует, что у [[scope]] есть свойство [[prototype]]. Просто сказано, что [[scope]]'ы формируют иерархию..
Отличная статья, материал не то чтобы сложный, но везде он как-то через назад описан, а тут - ясно и четко.
Кстати, в варианте "Веселой функции"
sum(1)(3) = 4
я бы посоветовал вычитание
sub(7)(8) = -1
гораздо нагляднее, что в какую очередь вызывается.
ИМХО.
Скажите, пожалуйста, а как оградить переменные во внешней фунции от внутренней? Сталкнулся с этой проблемой, когда писал рекурсивную функцию. Заранее спасибо.
Честно сказать, у меня брызнули слезы из глаз.. Я так долго пыталась понять, как работает Javascript, а тут прочитала - и за 5 минут все улеглось по полочкам. Огромное спасибо!
знаете, всё это, конечно, интересно и всё такое, но я бы попросил цвет скобок из зелёного сделать каким нибудь другим. например, синим или оранжевым, ибо зелёный на белом видно плохо и, чтоб отличить фигурную скобку от круглой, приходится глаза ломать... спасибо.
з.ы. ещё их можно обозначить полужирным шрифтом.
Потому что используя var x Вы объявляете локальную переменную x. Соответственно, она не существует, пока не будет инициализирована. А для ее инициализации должно выполнится условие, т.е. ее значение должно быть = 10.
var x = 10;
var f = function() { // тут x - локальная, x = undefined
if (x == 10) { // тут x до сих пор undefined
var x = 20; // тут x стало бы 20, но эта ветвь никогда не выполнится
}
return alert(x);
}
f();
Я думаю, x undefined, потому-что в месте вызова alert(x) есть две переменные x и интерпретатор не может определить, к какой из них он должен обратиться.
WalterScott, вы думаете не правильно. Еще раз внимательно прочтите статью и все станет понятно. B@rmaley.e><e все правильно написал выше.
Не забывайте, что интерпретатор проходится по скрипту дважды:
1. сначала собирает данные о локальных переменных (ищет var) и засовывает их в [[scope]]
2. потом начинает исполнять.
Одно непонятно - почему переменная x не инициализирована? Ведь при её объявлении через var в самом начале кода она сразу же и инициализируется значением 10
По всей вероятности, интерпретатор добавил к данному объекту вызова свойство "x" со значением "undefined", всему виной инструкция:
if (x == 10) {
var x = 20;
}
А точнее оператор "var". И не важно, где он находиться в коде функции, в этой области видимости "x" везде равен "undefined" (пока не присвоено другое значение, разумеется), если убрать "var" - код работает, но меняется значение глобальной переменной.
А вообще, рекомендую почитать раздел "4.3.1. Отсутствие блочной области видимости" в книге Флэнагана, там как-раз рассматривается этот вопрос.
Скорее всего из-за того, что var x=20; интерпретатор создаёт раньше чем происходит сравнение. Интерпретатору пофигу в какой части функции вы объявите переменную scope всё равно приклеивает к этой функции.
Когда интерпретатор начинает выполнять функцию f он находит все записи var и создает соответствующие переменные но присваивает в них значение undefined.
Далее, когда он перейдет уже непосредственно к выполнению кода значения установятся. Но поскольку x=undefined условие x==10 не выполнится, и значение не установится.
потому что интерпретатор выносит имена перемененных и функций в самый верх,
а только потом начинает выполнять код. Соответственно при сравнении (x == 10) значение берется из переменной х которая еще не инициализирована.
var x = 10;
var f = function () {
var x;
if (x == 10) { // x=undefined
x = 20;
}
alert(x);
}
f();
Добрый день!
Спасибо за статью, очень понятно и доступно!
У меня есть вопрос, не омгут ли замыкания вызывать memory leaks?
Например при создании обработчиков событий, когда и сам элемент ДОМ (например див в вашем примере) попадает в [[SCOPE]] и обработчик его события также держит ссылку на тот же [[SCOPE]].
Что произойдет, если например ДИВ будет удален из ДОМ модели?
Не просто могут но и вызывают утечки памяти! учитывая что юзается жабаскрипт столь массово и при этом столь гм, ...не слишком чтобы высокими программистами-профи... что надеяться на безошибочное и лишь к месту НЕ употребление var -- на это просто-таки надеяться никак не приходится...
Здравствуйте.
function outer() {
02 var outerVar;
03
04 var func = function() {
05 var innerVar
06 ...
07 x = innerVar + outerVar
08 }
09 return func
10 }
Можно ли возвращать переменную func без ()? У меня работает только так return func().
Может, я что-то не учла? Тогда что?
я не очень понял, считал что свойствами window становятся только объявленные вне функции глобальные переменные (без var). из статьи же будто бы следует, что свойствами window становятся все переменные, объявленные вне функции
Когда заканчивает работать функция outer, внутренняя функция func остается жить, ее можно запускать в другом месте кода. А вот такой вопрос: func остается в памяти только если ссылку на нее мы сохранили в глобальной переменной или даже если мы объявили внутреннюю функцию и не возвратили(присвоили) глобальной переменной ??
Правильно ли я понимаю, что в "Забавном примере" sum(a)(b) = a+b, мы можем обращаться к функции как sum(1)(2), использовать вторые скобки с параметром, потому что когда программа заходит в функцию sum(a) {... создается контекст исполнения, функция выполняется и при попадании на строчку return она должна выйти из функции, но перед этим создает ещё один контекст выполнения, так как там находится функция, после чего возвращает это значение. А это значение - ссылка на функцию, в результате чего получается как бы стандартная запись myFunc(b) (название функции в данном случае условное)?
Если мы не возвращаем функцию, но у нас есть различные функции внутри функции, то никакого замыкания не происходит?
Замыкание происходит вне зависимости от того, что Вы возвращаете.
function sum(a) {
sum.b = function(b) {
return a+b
};
return 5;
};
alert(sum(3)); // set a to 3
alert(sum.b(7)); // call b, 7 + 3 = 10
sum(3); // set a to 5
sum(21); // set a to 21
alert(sum.b(17)); // call b, 17 + 21 = 38
Оно происходит как раз в том случае, если Вы объявляете функцию внутри функции.
Тогда получается, что можно обращаться sum(a)(b) (из Забавного примера), потому что мы возвращаем функцию. А замыкание может быть не только при возвращении функции, главное, чтобы была объявлена внутренняя функция, из-за чего создастся Scope с теми параметрами, которые были в функции внешней и вызывать потом внутреннюю функцию с нужными параметрами, в итоге внутренняя функция будет обладать параметрами внешней. Это и есть замыкание? Если так, то какое-то странное название, потому что создается Область видимости для функции, которая видит все Области видимости вплоть до Глобальной области видимости.
Еще скажите, что все что здесь описывается это хорошо. Статья годная, спору нет. А вот такие тонкости на любителя, не хочу писать на JavaScript сложные программы.
У меня друг на работе пишет для гугл мапс маплеты на javascipt вплоть до вращения divов, так вот ниразу не сталкивался с такими проблемами, ни он ни я, когда писали разного рода приложения, если нет классов и объектов, так и не надо оперировать этими терминами и что-то выдумывать.
Вложенная функция не должна вообще получать доступ к переменным внешней функции если она уже закончила свою работу, этот scope должен уже улететь на фиг. А те переменные должны быть ==null
Илья, спасибо, статья хорошая.
Из логики приведенных определений, в статье значит ли, что всегда происходит замыкание, будь-то хоть просто объявленная функция?
Или будь то просто вложенные ф-и в которых не происходит оперирования никакими переменными?
Например:
function funcName() {
}
/* тут есть замыкание?, ведь в ф-ии funcName есть доступ к scope (которым явл. window) и интерпретатор не проводит анализ - понадобятся ли внутренней функции переменные ? */
function makefunc(x) {
return function() { }
}
/* тут тоже замыкание? ведь интерпретатор не проводит анализ - понадобятся ли внутренней функции переменные, а значит их вообще может не быть? */
function fn(x){
var x = x;
return function(y){
return x+y;
}
}
var test = fn(5);
alert(test(5)); // выведет 10
alert(test(10)); //выведет 15
В этом примере возвращаемая внутренняя функция "замыкает" в себе ссылки на переменные внешней функции. При этом переменная x существует только в области видимости функции fn (не в глобальной области), но возвращаемая анонимная функция продолжает иметь к ним доступ.
Спасибо что просветили, но общего смысла это не отменяет. Специально для Вас могу привести вот такой пример:
function counter(){
var cnt = 0;
return function(){
return ++cnt;
}
}
var test = counter();
alert(test()); //1
alert(test()); //2
Надеюсь отсутствие карринга сделает этот пример больше похожим на замыкание в Ваших глазах. И на будущее - в JavaScript каррирование это всегда замыкание, но замыкание не всегда каррирование.
Цель комментариев на этой странице - писать максимально осмысленный код для интерпретатора или писать максимально понятный человеку код, который раскрывает суть вопроса(псевдокод который работает)? С основами JavaScript я знаком, спасибо за беспокойство. У меня к Вам один вопрос - если Вы так хорошо знаете основы, то почему не потрудились сами ответить на вопрос человека "правильным" кодом?
Статья интересная. Хотя я пишу несколько лет, и были довольно лсожные проекты, однако всегда обходился без замыкания.
Не могли бы всё же сказать, где и для чего их необходимо испльзовть, пример задачи которая решается при помощи замыкания, и которую тяжело/невозможно/с_трудно_понятным_громоздким_кодом нельзя решить без замыканий?
Вещь коненчо инетресная, но вот никак не могу понять "а нафига?!".
Спасибо.
Есть много массивов из (пар некоторое значение, DOM узел). Назначить каждому узлу обработчик определенного события, внутри которого это некоторое значение просто выводится.
замыкания можно использовать для каких-либо сложных расчетов, которые должны выполняться только один раз. Пример:
function hard(){ return 10}; //тут какие-то сложные вычисления
var test = function(){
var x = hard(); //локальной переменной x присваивается результат выполнения функции hard
return function(y){ // возвращаем анонимную функцию которая использует переменную x
return x*y;
}
}(); //выполняем первую функцию, чтобы переменная x сразу имела результат, а переменная test имела значение функции замыкания использующего x
alert(test(5)); // выполняется внутренняя анонимная функция которая имеет доступ к уже готовому результату вычислений x = hard(). Результат = 50
Замыкания делают код чище и безопасней, так как хранимые переменные хранятся во внутреннем scope родительской функции(а не в глобальном), и доступ к ним имеет только возвращаемая функция. Вот еще пример, более простой:
function FormatCurrency(currencyName){
var currency = currencyName;
return function(price){
return price+' '+currency;
}
}
var roublesFormatter = new FormatCurrency('руб.'); //это важно создавать объект через "new" чтобы внутренняя переменная currency не перезаписалась, а создалась заново.
var dollarFormatter = new FormatCurrency('$');
alert(roublesFormatter(15)); // выведет "15 руб."
alert(dollarFormatter(15)); // выведет "15 $"
Нет никакой необходимости создавать новые экземпляры класса FormatCurrency.
Без new можно спокойно обойтись, поскольку переменная currency не является статическим свойством конструктора. Рекомендую проверить работу кода, удалив дескриптор new.
Насколько я знаю, замыкания очень удобны для разных паттернов проектирования. То есть именно для организации сложного кода, а не для решения какой-то тривиальной задачи.
Комраты есть вопрос, предвосхищая комментарии напишу: я три раза внимательно прочитал статью. Но так и не понял решения для моего вопроса. Изучаю работу с пространством имен, создаю свои методы и т.д. Но вот застрял при обращении к методу он мне возвращает значения которые я записал в someTab, и тут же вывожу в консоль чтобы посмотреть, что получилось - все нормально работает, но во второй раз в консоли он нам говорит, что переменная не определена. Почему это происходит я вроде как уже начал понимать. Но как это исправить хоть убейте не пойму. Уже мозг кипит потихоньку.
Почему сюда а не на форум потому что это наиболее похоже на проблемы затронутые в статье.
var Namespace = {};
Namespace = function() {
this.doSom = function{...};
};
onload = function() {
var nameSpaceObj = new Namespace();
var getSom = nameSpaceObj.doSom({
url:'country.xml',
success:function(data){
someTab = data;
console.log(someTab);
}
});
console.log(someTab);
};
Оказывается проблема не втом что переменная находится не в той области видимости а в том что просто console.log глобальной переменной выводится первым:) а та переменная все таки находитя там где и должна быть - в памяти.
var roublesFormatter = FormatCurrency('руб.');
var dollarFormatter = FormatCurrency('$');
т.е. без new, то при втором вызове FormatCurrency интерпретатор будет искать старую область видимости? - т.е. тот объект scope, который остался висеть в памяти?
не будет
т.к. это будет вызовом функции, а не ее присвоением
первый вариант возвращает функцию которая создается функцией
в вашем варианте просто вызовется функция, а в onclick попадет undefined
function addEvents2(divs) {
for(var i=0; i<divs.length; i++) {
divs[i].innerHTML = i
divs[i].onclick = function(x) {
return function() { alert(x) }
}(i) // что это ? что делает ?
}
}
Илья, смотри. Я хочу чтобы моя функция запоминала плейсхолдер и потом ставила его обратно если ничего не поменялось. Но что-то не работает с этими замыканиями. Либо я не правильно понял. Помоги
dominos.clearPlaceholder = function (){
var $thiz = $(this);
var val = $thiz.val();
var placeholder;
return function (){
if(val === ''){
$thiz.val(placeholder);
placeholder = null;
}else{
if(!placeholder){
placeholder = $thiz.val();
$thiz.val('');
}else{
placeholder = null;
}
}
};
};
$('.login_popup input').on('focus', dominos.clearPlaceholder).on('blur', dominos.clearPlaceholder);
Правильно ли я поняла, что для, например, для div 1 получается
onclick = function(x) {alert(x)} при этом в области видимости хранится x:1
для div2
onclick = function(x) {alert(x)} при этом в области видимости хранится x:2
Получается мы передаем в onclick функцию с ее областью видимости.
а если без замыканий, тогда получается, что onclick для div 1 будет
onclick = function {alert(i)} и он возьмет i из внешней функции и для div2 будет аналогично.
Помогите новичку. Я вроде поняла, но чувствую, что еще плаваю.
Функция addHideHandler приводит к желаемому результату (сокрытию стороннего элемента) только, когда нажмешь на первый элемент два раза. Может, для функции addHideHandler следует ввести оператор return? Или это для того, чтобы люди лишний раз подумали? ))
"Интерпретатор javascript не проводит анализ - понадобятся ли внутренней функции переменные из внешней, и какие переменные могут быть нужны.
Вместо этого он просто оставляет весь [[scope]] внешней функции в живых.
Чтобы когда внутренняя функция запустится, если она вдруг не найдет какую-либо переменную в своем [[scope]] - она могла обратиться к [[scope]] внешней функции и нашла бы ее там."
Это неверно. Скоуп внешней функции не уничтожается из-за особенностей работы сборщика мусора. Пока на какой-либо объект существует хоть одна ссылка из другого контекста (в данном случае ссылка на [[scope]] внешней функции из внутренней функции) этот объект не может быть уничтожен сборщиком мусора. Причина в этом а не в том что внутренней функции МОЖЕТ понадобиться переменная из внешней функции
Одна из переменных может не перидоваться сервером. Нужно проверит php script. Может отсутствовать a.responseText; Или являться пустой строкой. А может и не быть aspan Но его вообще негде не видно.
так как вызывается функция aajax , а не onreadystatechange , то соответственно функция aajax возвращяет undefined.
что-бы переменная приняла значение можно воспользоваться callback функцией:
function at1cx(id) {
var aname;
aajax(id, function (res) {
aname = res;
});
}
function aajax(id, callback) {
var a = new XMLHttpRequest();
var b = false;
a.open("GET", "a.php?a=" + id.value, true);
a.onreadystatechange = function () {
if (a.readyState == 4)
if (a.status == 200) {
aspan.innerHTML = a.responseText;
if (a.responseText > 0)
callback('F');
else
callback('T');
}
}
a.send(null);
}
Автор - это редкий случай, когда у программиста получается писать статьи не только для таких же программистов, но и для обычных людей.
Спасибо, Илья, за вашу работу.
Здравствуйте. Подскажите пожалуйста, как можно написать код в данной ситуации:
У меня n количество маленьких картинок и 1 большая. При нажатии на любую из маленьких картинок, нужно большую убирать, а вместо нее ставить маленькую с уникальным id (в качестве идентификатора, можно использовать название маленькой картинки, 101.jpeg). Этот id нужно присвоить глобальной переменной.
<script>
Вот тут не понятно, что написать, чтобы шла смена картинок с присвоением id маленькой картинки?
</script>
нагляднее для изучающих было бы выложить весь код "верных" и "неверных" функций, чтоб они у себя в Notepad++ погоняли код, вот, выкладываю этот пример с html- разметкой и кодом JS:
<!doctype html>
<html lang="ru">
<head>
<title>Спящий onclick при вызове внутренней функции вызывает для внутренней функции внешний LE момента ОКОНЧАНИЯ выполнения внешней функции</title>
<meta charset="utf-8">
</head>
<body>
<p>
<input type="button" onclick="testEvents()" value="запускаем функцию testEvents()">
</p>
<p><input type="button" onclick="testEvents2()" value="запускаем функцию testEvents2()"></p>
<div id="events1"></div>
<div id="events2"></div>
</div>
[js]
<script>
function makeDivs(parentId) {
for (var i=0;i<10;i++) {
var j = 9-i; //j будет 9, 8, 7, 6 ...0
var div = document.createElement('div');
div.style.backgroundColor = '#'+i+i+j+j+j+i
div.className="closure-div"
div.style.color = '#'+j+j+i+i+i+j
document.getElementById(parentId).appendChild(div)
//все верно: она тут строит рядок из div, варьируя цвета
}
}
function testEvents() {
makeDivs('events1')// отдаем стринг-значение id <div id="events1"></div>
addEvents(document.getElementById('events1').childNodes)
//.childNodes берет массив дочерних элементов, функция makeDivs(parentId)) запиздячила туда рядок из них (разных цветов)
}
function addEvents(divs) { // вот якобы ошибочная функция
for(var i=0; i<divs.length; i++) { //получила массив дочерних div, будет расставлять на них циферки, выводимые при .onclick
divs[i].innerHTML = i
divs[i].onclick = function() { alert(i) } // вот эта i в alertе почему-то будет 10, в этом и закавыка, вроде как по логике должны быть от 0 до 10. Тут соль задачи.Учебник говорит: "Такой глюк возник из-за того, что все функции div[i].onclick получают значение i из одного на всех [[scope]] внешней функции. А это значение ([[scope]].i) НА МОМЕНТ АКТИВАЦИИ ONCLICK-ОБРАБОТЧИКА РАВНО 10 (цикл завершился как только i==10)". ТО ЕСТЬ внутренняя функция хватает значение i именно НА МОМЕНТ АКТИВАЦИИ ONCLICK-ОБРАБОТЧИКА, а это 10. То есть внутреннее поле переменных как бы в ином временном измерении, оно хватает из внешнего lexical evironment именно на момент активации .onclick значение i. При .onclick имеется как бы спящая внутренняя функция, которая при активации просыпается и хватает самое последенее значение из внешнего lexical evironment, а оно тут 10. Это скорее особенность обработчика событий .onclick
}
}
function testEvents2() {
makeDivs('events2')
addEvents2(document.getElementById('events2').childNodes)
//.childNodes берет массив дочерних элементов, тут он пока пустой)
}
function addEvents2(divs) {
for(var i=0; i<divs.length; i++) {
divs[i].innerHTML = i
divs[i].onclick = function(x) {
return function() { alert(x) }
}(i) // а вот тут мы запихиваем именно из внешней функции значение i КАЖДОГО ОБОРОТА
}
}
</script>[/js]
</body>
</html>
(поспешил отправить)
мне кажется многое станет ясно и прозрачно, если будет чёткое понимание алгоритма процесса "уборки мусора".
хотя в разных браузерах это может реализовано по разному.
в Спецификации то же ничего нет.
It was a very good post indeed. I thoroughly enjoyed reading it in my lunch time.
Will surely come and visit this blog more often. Thanks for sharing. 먹튀검증
It's really nice and meanful. it's really cool blog. Linking is very useful thing.you have really helped lots of people who visit blog and provide them usefull information. Best dentist in Chico
Thanks for sharing this information. I really like your blog post very much. You have really shared a informative and interesting blog post with people. Toronto Website Design
I discovered your site ideal for me. It consists of wonderful and useful posts. I've read many of them and also got so much from them. In my experience, you do the truly amazing.Truly i'm impressed out of this publish 먹튀검증
WooDonations is the best woocommerce donations plugin for your store. that use to collect donations on your websites based on WooCommerce. It is a great way to raise funds for NGOs, Charities, and other causes.
That will help you collect online donations using PayPal, Stripe, WooCommerce, other credit card processors, and even cryptocurrency.
Also Check - woocommerce single product page customizer woocommerce manage stock
Автор - это редкий случай, когда у программиста получается писать статьи не только для таких же программистов, но и для обычных людей.
Спасибо, woodoku Илья, за вашу работу.
Your writing is perfect and complete. 바카라사이트 However, I think it will be more wonderful if your post includes additional topics that I am thinking of. I have a lot of posts on my site similar to your topic. Would you like to visit once?
I think about it every time I read your article, but you have a really great insight. Among the people I know online and offline, your insight is at the highest level. That's why I love your blog. I hope you continue to post good comments. 메이저토토사이트
I think about it every time I read your article, but you have a really great insight. Among the people I know online and offline, your insight is at the highest level. That's why I love your blog. I hope you continue to post good comments. 메이저토토사이트
There are a lot of fun, free games available on the internet these days, I usually play flagle because it's great for a lot of people, it feels so much fun when I guess the crossword correctly and get the highest score, are you ready to play? It's so remarkable that I can't help but come across this precious information whenever I surf the internet, thank you very much
Thank you for your post. I have read through several similar topics! However, your article gave me a very special impression, unlike other articles. I hope you continue to have valuable articles like this or more to share with everyone! trap the cat
YouTube Trends is the best website for seeing YouTube trending videos in one place across the world. On YouTube Trends you can watch every category of video like Gaming, Music, Sports, News, Movies, Science & Technology, etc. Pick your favorite one and watch what is trending on youtube today. The list is hourly updated so you can get the latest trending videos on youtube
Область видимости — важная концепция, определяющая доступность переменных. Данная концепция лежит в основе замыканий dinosaur game, разделяя переменные на глобальные и локальные.
I do believe this is an excellent web site. I stumbledupon it ???? I may return yet again since I bookmarked it. Money and freedom is the greatest way to change, may you be rich and continue to help other people. betflikvip
I read good articles and comments here and leave comments with a lot of help. Thank you. I ll grow up and spread good comments. 도파민 접속주소 먹튀폴리스 검증업체를 통해 안전한 카지노사이트
Please let me know if you’re looking for a article writer for your site. You have some really great posts and I feel I would be a good asset. If you ever want to take some of the load off, I’d absolutely love to write some material for your blog in exchange for a link back to mine. Please send me an email if interested. Thank you 바카라사이트 I couldn't think of this, but it's amazing! I wrote several posts similar to this one, but please come and see!!
Если описать концепцию функционального программирования простыми словами, то окажется, что это — подход к программированию, при использовании которого функции можно передавать другим функциям в качестве параметров и использовать функции в качестве значений trap the cat, возвращаемых другими функциями. Занимаясь функциональным программированием, мы проектируем архитектуру приложения и пишем код с использованием функций.
I finally found what I was looking for! I'm so happy. 온라인카지노 Your article is what I've been looking for for a long time. I'm happy to find you like this. Could you visit my website if you have time? I'm sure you'll find a post of interest that you'll find interesting.
hjul
Your writing is excellent, so allow me to share a little of myself. One of the best available limitless running games is run 3. Control your ball as you compete in a fast ramp race to see how far you can climb the leaderboard.
This article is a testament to your heardle dedication and hard work, and it really shows in the content of the article. I know you put a lot of effort into this post.
Buy gift cards online
Buy gift cards in dollar amounts ranging from $15 to $500. It is easy to check your gift card balance and get gift card help online, and there are no fees or expiration dates to worry about. Usable online or in store, Best Buy Gift Cards and online gift cards are the perfect gift to ensure your friends and family get the gifts on their wish list.
Hello, I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once
What a nice post! I'm so happy to read this. 토토사이트추천 What you wrote was very helpful to me. Thank you. Actually, I run a site similar to you. If you have time, could you visit my site? Please leave your comments after reading what I wrote. If you do so, I will actively reflect your opinion. I think it will be a great help to run my site. Have a good day.
All of the information I’ve gleaned from it basically has been quite useful , and I’d for the most part want to generally commend you on really your abilities, actually contrary to popular belief five nights at freddy's.
Eine weitere wichtige Funktion von Freemail ist die Möglichkeit, E-Mails von anderen E-Mail-Diensten zu importieren. Dies ist eine nützliche Funktion für Nutzer, die zuvor einen anderen E-Mail-Dienst genutzt haben und ihre alten E-Mails auf ihr neues Freemail-Konto übertragen möchten. Die Plattform unterstützt eine Vielzahl von Formaten, einschließlich IMAP und POP3.
That's a really impressive new idea! 먹튀검증 It touched me a lot. I would love to hear your opinion on my site. Please come to the site I run once and leave a comment. Thank you.
"3D Jewelry Rendering" refers to the process of creating realistic digital representations of jewelry using three-dimensional computer graphics. It involves using specialized software and techniques to simulate materials, lighting, and textures, allowing designers and customers to visualize and evaluate jewelry designs before they are physically produced.
I was recommended this blog through a friend from school. No one understood my problem, but I looked at your blog and solved the problem. I will share information about to my friends. I like your blog very much. good luck. 먹튀검증사이트
Great post i must say and thanks for the information. Education is definitely a sticky subject. However, is still among the leading topics of our time. Thanks 안전메이저사이트
Usually keep it up! Nicely i in reality favored analyzing it. This subject supplied by using you could be very practical for proper planning. What’s up, i read your weblog daily. Your writing fashion is 토토사이트
A closure is a function that can access a variable belonging to the scope that contains it (closure function), even when the dino game scope that contains it has finished executing. Specifically, closures can access variables declared in the function that created the closure, even after the function that created it has finished executing.
A closure is a function that can access a variable belonging to the scope that contains it (closure function), even when the dino game scope that contains it has finished executing. Specifically, closures can access variables declared in the function that created the closure, even after the function that created it has finished executing.
I learned a lot from your blog, and you can learn more about older video games to have more engaging experiences. I look forward to playing with you in the past! retro games
I have been reading your blog posts for month and its been the greatest thing I am doing in past few months. keep up the good work for sharing the information. pgslot168 login" title="pgslot168 login">pgslot168 login
Good post, thanks for sharing.. very useful for me, I will bookmark this for my future needs. I would like to thank you for the efforts you have made in writing this article and I am hoping the same best work from you in the future as well. ยูฟ่า168
Pretty nice post. I just stumbled upon your blog and wished to say that I have really enjoyed surfing around your blog posts. After all I’ll be subscribing to your feed and I hope you write again very soon! เบทฟิกvip
I’m pretty pleased to discover this site. I wanted to thank you for your time just for this fantastic read!! I definitely really liked every bit of it and i also have you saved as a favorite to check out new stuff on your site. bio gaming
Closures in programming are a powerful concept often used in languages that support functional programming suika game paradigms or have functional aspects.
KinitoPET is an exciting and addictive dice game that combines luck and strategy. Players roll dice to achieve specific combinations and earn points. The goal is to score the highest possible total and beat opponents. With its simple rules and dynamic gameplay, KinitoPET offers endless fun for all ages.
Понимание замыканий, безусловно, является ключевым понятием в программировании на JavaScript! Поначалу это может быть сложно, но освоить это будет полезно. Из интересных задач, пробовали ли вы VR-игру Monkey Mart? Управление собственным магазином и удовлетворение потребностей клиентов требует некоторых навыков быстрого мышления и решения проблем, точно так же, как и решение замыканий в JavaScript!
I am always searching online for articles that can help me. There is obviously a lot to know about this. I think you made some good points in Features also. Keep working, great job! เว็บจ่ายไว
Absolutely agree! Having the right pair of eyeglasses not only enhances your vision but also elevates your style. For the Best Online Glasses in Pakistan and to Buy Original Affordable Sunglasses, visit our website and explore our extensive collection of frames and lenses. Proper eye care is essential for clear vision for years to come.
The content discusses the powerful yet often misunderstood concept of closures in JavaScript. While closures can pose challenges, they also offer remarkable advantages when wielded correctly. Much like in the online game Monkey Mart, where strategic management maximizes profits, understanding closures allows developers to manage their code with efficiency and precision. Embracing closures can lead to cleaner, more effective programming, similar to how players optimize their resources in the game. Understanding this can transform potential pitfalls into powerful tools, enhancing one's coding experience.
The content explores closures in JavaScript, highlighting their dual nature: challenging yet powerful when mastered. Similar to Monkey Mart where strategic management boosts profits, understanding closures empowers developers to efficiently manage code. Embracing closures enhances programming, akin to optimizing resources in the game. This transformation turns coding pitfalls into potent tools, enriching the coding journey.
Good day! This post couldn’t be written any better! Reading this post reminds me of my old room mate! He always kept talking about this.
Jasa Pengacara Jabodetabek
Good day! This post couldn’t be written any better! Reading this post reminds me of my old room mate! He always kept talking about this.
Jasa Pengacara Jabodetabek Pengacara Perceraian
THE ONE CARGO ชิปปิ้ง จีนคุณภาพ ที่ผู้ประกอบการไว้ใจ บริการนำเข้าสินค้าจากจีนมาไทย ส่งเร็วได้มาตรฐาน เปิดบริการทุกวัน นำเข้าสินค้าจากจีน เอกสารครบถ้วนถูกต้อง ใบขน ใบกำกับ ใบ Form E ขนส่งทางรถ ระยะเวลา 3-5 วัน
Замыкание в JavaScript – мощный инструмент, который часто недооценивают, как неподходящая тема для беседы на Omegle. Хотя замыкания могут вызвать проблемы, при правильном понимании они открывают множество возможностей для создания эффективного кода. Осваивая замыкания, вы можете улучшить свои навыки программирования, а также сделать взаимодействие более увлекательным, даже на таких платформах, как Omegle.
Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены. Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
На моем браузере вывод "makeDivs + addEvents" и "makeDivs + новая функция" отображаются одинаково.
Да, makeDivs должны отображаться одинаково. Но работают по-разному.
Расскажите плз. про последниий пример поподробнее, я ничего не понял
>>alert( function a(){ return [5] }()[0] ) // => выведет 5
и чуть выше тоже
Ок, спасибо. Сделал эту часть подробнее.
Отличная статья. спасибо
спасибо. была проблема. разобрался.
Спасибо за статью.
Возник вопрос по работе с локальными переменными в таких случаях в отладчике Firebug.
В этом примере
var xx = 20;
(function(){
var xx = 10;
func = function(){
alert(xx);
}
})();
func();
отладчик Firebug при вызове функции func()
показывает что xx = 20, хотя alert() выводит правильное значение 10.
Как следить за переменной из [[scope]] функции func ??
В вашем коде нет явного вызова отладчика командой
debugger
. Вставьте ее, чтобы понимать точное место вызова в коде.Спасибо за столь подробное объянение
Отличная статья, спасибо огромное!
Молодцы спасибо за статью!
Спс... очень признателен!
Не лишне было бы упомянуть, что замыкания можно организовать и с использованием неанонимных внутренних функций.
You must to visit our web platform for your own sexy chat pleasure in United Kingdom sexchat
Очень похоже, что [[scope]].[[prototype]] вложенной функции == [[scope]] внешней. Это действительно так, или я ошибаюсь?
Речь идет просто об иерархии, в чем-то аналогичной наследованию через прототипы.
Однако, насколько я понимаю - из стандарта (http://javascript.ru/ecma/part10#a-10.1.4) не следует, что у [[scope]] есть свойство [[prototype]]. Просто сказано, что [[scope]]'ы формируют иерархию..
Спасибо. Очень интересно и понятно!
Спасибо за столь подробное объянение
Отлично!
хорошая статья) первый раз вижу такое на русском языке)
Спасибо! На русском аналогов не видел, по моему даже на википедии нет!
Отличная статья, материал не то чтобы сложный, но везде он как-то через назад описан, а тут - ясно и четко.
Кстати, в варианте "Веселой функции"
sum(1)(3) = 4
я бы посоветовал вычитание
sub(7)(8) = -1
гораздо нагляднее, что в какую очередь вызывается.
ИМХО.
Скажите, пожалуйста, а как оградить переменные во внешней фунции от внутренней? Сталкнулся с этой проблемой, когда писал рекурсивную функцию. Заранее спасибо.
Подозреваю, что вам поможет слово var.
Спасибо! очень толково и понятно освящен такой сложный для меня вопрос)
Честно сказать, у меня брызнули слезы из глаз.. Я так долго пыталась понять, как работает Javascript, а тут прочитала - и за 5 минут все улеглось по полочкам. Огромное спасибо!
знаете, всё это, конечно, интересно и всё такое, но я бы попросил цвет скобок из зелёного сделать каким нибудь другим. например, синим или оранжевым, ибо зелёный на белом видно плохо и, чтоб отличить фигурную скобку от круглой, приходится глаза ломать... спасибо.
з.ы. ещё их можно обозначить полужирным шрифтом.
Спасибо за очень хорошую статью.
Добрый день. У меня возник следующий вопрос. Что и в каких scope происходит со свойством x в данном примере:
Почему в результате я получаю undefined?
Вот это работает как надо, вот только почему не работает при var x=20; мне непонятно... Как вариант, некорректная запись условия. Надо копать мануал.
Потому что используя var x Вы объявляете локальную переменную x. Соответственно, она не существует, пока не будет инициализирована. А для ее инициализации должно выполнится условие, т.е. ее значение должно быть = 10.
Я думаю, x undefined, потому-что в месте вызова alert(x) есть две переменные x и интерпретатор не может определить, к какой из них он должен обратиться.
WalterScott, вы думаете не правильно. Еще раз внимательно прочтите статью и все станет понятно. B@rmaley.e><e все правильно написал выше.
Не забывайте, что интерпретатор проходится по скрипту дважды:
1. сначала собирает данные о локальных переменных (ищет var) и засовывает их в [[scope]]
2. потом начинает исполнять.
B@rmaley.e>e
не совсем так, вернее вот так:
http://javascript.ru/blog/Dmitry-A.-Soshnikov/Tonkosti-ECMA-262-3.-CHast-2.-Obekt-peremennyh.#obekt-peremennyh-v-kontekste-funkcii
Поэтому Ваши слова в виде:
больше отражают суть.
Одно непонятно - почему переменная x не инициализирована? Ведь при её объявлении через var в самом начале кода она сразу же и инициализируется значением 10
По всей вероятности, интерпретатор добавил к данному объекту вызова свойство "x" со значением "undefined", всему виной инструкция:
А точнее оператор "var". И не важно, где он находиться в коде функции, в этой области видимости "x" везде равен "undefined" (пока не присвоено другое значение, разумеется), если убрать "var" - код работает, но меняется значение глобальной переменной.
А вообще, рекомендую почитать раздел "4.3.1. Отсутствие блочной области видимости" в книге Флэнагана, там как-раз рассматривается этот вопрос.
Спасибо за ссылку на 4.3.1 - все сразу встало на свои места =)
Скорее всего из-за того, что var x=20; интерпретатор создаёт раньше чем происходит сравнение. Интерпретатору пофигу в какой части функции вы объявите переменную scope всё равно приклеивает к этой функции.
покажу сказанное:
shemales glasgow is great web platform for lonley guys to make chat contacts in UK
YouTube Trendy is the platform, where you can find the top 50 YouTube trending videos from all over the world.
Also provides popular categories of videos from YouTube. Categories like: Gaming, Music, Sports, News, Movies, Science & Technology, etc.
Ответ через 3 года )
Когда интерпретатор начинает выполнять функцию f он находит все записи var и создает соответствующие переменные но присваивает в них значение undefined.
Далее, когда он перейдет уже непосредственно к выполнению кода значения установятся. Но поскольку x=undefined условие x==10 не выполнится, и значение не установится.
потому что интерпретатор выносит имена перемененных и функций в самый верх,
а только потом начинает выполнять код. Соответственно при сравнении (x == 10) значение берется из переменной х которая еще не инициализирована.
var x = 10;
var f = function () {
var x;
if (x == 10) { // x=undefined
x = 20;
}
alert(x);
}
f();
Вот так работает.
Как вы отнесетесь, если я сделаю перевод вашей статьи на английский язык с указанием оригинала, т.е. вашей статьи?
Вопрос про конструкцию:
Что происходит "внутри" когда используются круглые скобки ( … )?
Иллюстрация:
а эта запись о чем говорит fn(p)(p)
Ни о чем, это вообще exception.
отличная статья!
предельно понятное изложение сути
спасибо большое)
все вроде понятно особенно со [[scope]], но вот "забавный" пример я вообще понять не могу! Не могли бы Вы его объяснить... спасибо
Добрый день!
Спасибо за статью, очень понятно и доступно!
У меня есть вопрос, не омгут ли замыкания вызывать memory leaks?
Например при создании обработчиков событий, когда и сам элемент ДОМ (например див в вашем примере) попадает в [[SCOPE]] и обработчик его события также держит ссылку на тот же [[SCOPE]].
Что произойдет, если например ДИВ будет удален из ДОМ модели?
Не просто могут но и вызывают утечки памяти! учитывая что юзается жабаскрипт столь массово и при этом столь гм, ...не слишком чтобы высокими программистами-профи... что надеяться на безошибочное и лишь к месту НЕ употребление var -- на это просто-таки надеяться никак не приходится...
Спасибо огромное! Уникальная статья на русском.
Обязательно рекомендую к прочтению!
Вопрос: значит "замыкание" - это closure. А что такое enclosure?
Здравствуйте.
function outer() {
02 var outerVar;
03
04 var func = function() {
05 var innerVar
06 ...
07 x = innerVar + outerVar
08 }
09 return func
10 }
Можно ли возвращать переменную func без ()? У меня работает только так return func().
Может, я что-то не учла? Тогда что?
Это в самом верху страницы
интересно вот что. почему замыкания не работают с функциями создаваемыми через new Function()?
var outer = function() {
var local = "works";
var inner = new Function("alert(local);");
return inner;
};
outer()();
ReferenceError: loc is not defined.
[[scope]] не передается? или все-таки поиск имени local не так просто ведется?
сорри, local в тексте ошибки вместо loc.
я не очень понял, считал что свойствами window становятся только объявленные вне функции глобальные переменные (без var). из статьи же будто бы следует, что свойствами window становятся все переменные, объявленные вне функции
Для window все переменные локальны, что с var, что без. И это в общем то логично.
если я переменную объявляю вне функции, но с var, то она остается глобальной или нет?
становится, попробуй написать вне функции var p=12; а потом где-нибудь alert(window.p) или alert(window['p'])
Когда заканчивает работать функция outer, внутренняя функция func остается жить, ее можно запускать в другом месте кода. А вот такой вопрос: func остается в памяти только если ссылку на нее мы сохранили в глобальной переменной или даже если мы объявили внутреннюю функцию и не возвратили(присвоили) глобальной переменной ??
Ну как я понимаю, если мы ссылку не сохранили, то объект функция уничтожится после того, как отработает внешняя функция.
Правильно ли я понимаю, что в "Забавном примере" sum(a)(b) = a+b, мы можем обращаться к функции как sum(1)(2), использовать вторые скобки с параметром, потому что когда программа заходит в функцию sum(a) {... создается контекст исполнения, функция выполняется и при попадании на строчку return она должна выйти из функции, но перед этим создает ещё один контекст выполнения, так как там находится функция, после чего возвращает это значение. А это значение - ссылка на функцию, в результате чего получается как бы стандартная запись myFunc(b) (название функции в данном случае условное)?
Если мы не возвращаем функцию, но у нас есть различные функции внутри функции, то никакого замыкания не происходит?
Замыкание происходит вне зависимости от того, что Вы возвращаете.
Оно происходит как раз в том случае, если Вы объявляете функцию внутри функции.
Тогда получается, что можно обращаться sum(a)(b) (из Забавного примера), потому что мы возвращаем функцию. А замыкание может быть не только при возвращении функции, главное, чтобы была объявлена внутренняя функция, из-за чего создастся Scope с теми параметрами, которые были в функции внешней и вызывать потом внутреннюю функцию с нужными параметрами, в итоге внутренняя функция будет обладать параметрами внешней. Это и есть замыкание? Если так, то какое-то странное название, потому что создается Область видимости для функции, которая видит все Области видимости вплоть до Глобальной области видимости.
Да, так оно и есть. Ну а название как название, по-моему. Никто же не жалуется, что инкапсуляция инкапсуляцией называется.
в десятой строчке только не понятно почему а сетится в пять, а не в три...
Еще скажите, что все что здесь описывается это хорошо. Статья годная, спору нет. А вот такие тонкости на любителя, не хочу писать на JavaScript сложные программы.
Такие тонкости встречаются в JS сплошь и рядом. Любой разработчик среднего уровня должен их знать.
У меня друг на работе пишет для гугл мапс маплеты на javascipt вплоть до вращения divов, так вот ниразу не сталкивался с такими проблемами, ни он ни я, когда писали разного рода приложения, если нет классов и объектов, так и не надо оперировать этими терминами и что-то выдумывать.
Вложенная функция не должна вообще получать доступ к переменным внешней функции если она уже закончила свою работу, этот scope должен уже улететь на фиг. А те переменные должны быть ==null
Воистину, нечего ответить, кроме, разве что, замечания по поводу того, что лечить мертвых - занятие более перспективное.
Реально спасибо, всё очень просто, понятно и полезно... как, впрочем, и все статьи на этом сайте!
Где указано количество дивов?
Илья, спасибо, статья хорошая.
Из логики приведенных определений, в статье значит ли, что всегда происходит замыкание, будь-то хоть просто объявленная функция?
Или будь то просто вложенные ф-и в которых не происходит оперирования никакими переменными?
Например:
Еще вопрос. Уточните пожалуйста для ясности восприятия термина замыкание, что на чем замыкается?
Классическое замыкание выглядит примерно так:
В этом примере возвращаемая внутренняя функция "замыкает" в себе ссылки на переменные внешней функции. При этом переменная x существует только в области видимости функции fn (не в глобальной области), но возвращаемая анонимная функция продолжает иметь к ним доступ.
поведаю, это каррингом называется
Спасибо что просветили, но общего смысла это не отменяет. Специально для Вас могу привести вот такой пример:
Надеюсь отсутствие карринга сделает этот пример больше похожим на замыкание в Ваших глазах. И на будущее - в JavaScript каррирование это всегда замыкание, но замыкание не всегда каррирование.
я знаю, что это такое, и могу отличить одно от другого. мне можете не обьяснять
bolgovr, вам бы самому основы подъучить;)
Если что, оператор var тут игнорируется, а переменной x присвытвается значение переменной x.
Цель комментариев на этой странице - писать максимально осмысленный код для интерпретатора или писать максимально понятный человеку код, который раскрывает суть вопроса(псевдокод который работает)? С основами JavaScript я знаком, спасибо за беспокойство. У меня к Вам один вопрос - если Вы так хорошо знаете основы, то почему не потрудились сами ответить на вопрос человека "правильным" кодом?
Статья интересная. Хотя я пишу несколько лет, и были довольно лсожные проекты, однако всегда обходился без замыкания.
Не могли бы всё же сказать, где и для чего их необходимо испльзовть, пример задачи которая решается при помощи замыкания, и которую тяжело/невозможно/с_трудно_понятным_громоздким_кодом нельзя решить без замыканий?
Вещь коненчо инетресная, но вот никак не могу понять "а нафига?!".
Спасибо.
Есть много массивов из (пар некоторое значение, DOM узел). Назначить каждому узлу обработчик определенного события, внутри которого это некоторое значение просто выводится.
замыкания можно использовать для каких-либо сложных расчетов, которые должны выполняться только один раз. Пример:
Замыкания делают код чище и безопасней, так как хранимые переменные хранятся во внутреннем scope родительской функции(а не в глобальном), и доступ к ним имеет только возвращаемая функция. Вот еще пример, более простой:
Нет никакой необходимости создавать новые экземпляры класса FormatCurrency.
Без new можно спокойно обойтись, поскольку переменная currency не является статическим свойством конструктора. Рекомендую проверить работу кода, удалив дескриптор new.
Насколько я знаю, замыкания очень удобны для разных паттернов проектирования. То есть именно для организации сложного кода, а не для решения какой-то тривиальной задачи.
Комраты есть вопрос, предвосхищая комментарии напишу: я три раза внимательно прочитал статью. Но так и не понял решения для моего вопроса. Изучаю работу с пространством имен, создаю свои методы и т.д. Но вот застрял при обращении к методу он мне возвращает значения которые я записал в someTab, и тут же вывожу в консоль чтобы посмотреть, что получилось - все нормально работает, но во второй раз в консоли он нам говорит, что переменная не определена. Почему это происходит я вроде как уже начал понимать. Но как это исправить хоть убейте не пойму. Уже мозг кипит потихоньку.
Почему сюда а не на форум потому что это наиболее похоже на проблемы затронутые в статье.
Извните разобрался!
Оказывается проблема не втом что переменная находится не в той области видимости а в том что просто console.log глобальной переменной выводится первым:) а та переменная все таки находитя там где и должна быть - в памяти.
А если в предыдущем примере написать:
var roublesFormatter = FormatCurrency('руб.');
var dollarFormatter = FormatCurrency('$');
т.е. без new, то при втором вызове FormatCurrency интерпретатор будет искать старую область видимости? - т.е. тот объект scope, который остался висеть в памяти?
Здравствуйте!
Добавьте пожалуйста в статью явное указание, что аргументы функции также записываются в [[scope]]. (У меня по крайней мере записываются
function addEvents2(divs) {
for(var i=0; i
разве так:
function addEvents2(divs) {
for(var i=0; i
не будет работать как ожидается?
разве так:
не будет работать как ожидается?
не будет
т.к. это будет вызовом функции, а не ее присвоением
первый вариант возвращает функцию которая создается функцией
в вашем варианте просто вызовется функция, а в onclick попадет undefined
самая лучшая статья из всех что я видел за много лет на эту тему...
Пора бы уже комменты прятать в AJAX загрузчик, 90% инфы на странице бесполезные комменты.
вызывает безымянную функцию function(x) с параметром x = i
Очень интересно узнать, когда использование замыкания - вреднО.
Илья, смотри. Я хочу чтобы моя функция запоминала плейсхолдер и потом ставила его обратно если ничего не поменялось. Но что-то не работает с этими замыканиями. Либо я не правильно понял. Помоги
Ваша функция возвращает функцию, но возвращенная так и не вызывается. Попробуйте так:
Правильно ли я поняла, что для, например, для div 1 получается
onclick = function(x) {alert(x)} при этом в области видимости хранится x:1
для div2
onclick = function(x) {alert(x)} при этом в области видимости хранится x:2
Получается мы передаем в onclick функцию с ее областью видимости.
а если без замыканий, тогда получается, что onclick для div 1 будет
onclick = function {alert(i)} и он возьмет i из внешней функции и для div2 будет аналогично.
Помогите новичку. Я вроде поняла, но чувствую, что еще плаваю.
Функция addHideHandler приводит к желаемому результату (сокрытию стороннего элемента) только, когда нажмешь на первый элемент два раза. Может, для функции addHideHandler следует ввести оператор return? Или это для того, чтобы люди лишний раз подумали? ))
"Интерпретатор javascript не проводит анализ - понадобятся ли внутренней функции переменные из внешней, и какие переменные могут быть нужны.
Вместо этого он просто оставляет весь [[scope]] внешней функции в живых.
Чтобы когда внутренняя функция запустится, если она вдруг не найдет какую-либо переменную в своем [[scope]] - она могла обратиться к [[scope]] внешней функции и нашла бы ее там."
Это неверно. Скоуп внешней функции не уничтожается из-за особенностей работы сборщика мусора. Пока на какой-либо объект существует хоть одна ссылка из другого контекста (в данном случае ссылка на [[scope]] внешней функции из внутренней функции) этот объект не может быть уничтожен сборщиком мусора. Причина в этом а не в том что внутренней функции МОЖЕТ понадобиться переменная из внешней функции
Помогите зациклить
Спасибо. Удружили доступно изложенной информацией.
Замыкание - одно из мощных выразительных средств javascript, которым часто пренебрегают, и даже не советуют употреблять.
Действительно, замыкания могут приводить к проблемам.
эти слова я думаю стоит выделить красным жирным написанием размером в 200 пикселей на букву
Привет!
Почему Я не могу получить значение return в переменную aname?
Выводит undefined.
А как получить значение return?
Одна из переменных может не перидоваться сервером. Нужно проверит php script. Может отсутствовать a.responseText; Или являться пустой строкой. А может и не быть aspan Но его вообще негде не видно.
так как вызывается функция aajax , а не onreadystatechange , то соответственно функция aajax возвращяет undefined.
что-бы переменная приняла значение можно воспользоваться callback функцией:
function at1cx(id) {
var aname;
aajax(id, function (res) {
aname = res;
});
}
function aajax(id, callback) {
var a = new XMLHttpRequest();
var b = false;
a.open("GET", "a.php?a=" + id.value, true);
a.onreadystatechange = function () {
if (a.readyState == 4)
if (a.status == 200) {
aspan.innerHTML = a.responseText;
if (a.responseText > 0)
callback('F');
else
callback('T');
}
}
a.send(null);
}
Спасибо очень помоги =)
Теперь можно делать кросс браузерные табы.
Вот еще простой пример замыкания:
var object = {
index: 0,
add: function() {
this.index++;
return this; //дает возможность вызывать функции цепочкой
},
get: function() {
return this.index;
}
};
object.add().add().add().get(); // >> 3
Большое спасибо.
Очень понятно все написано.
Полдня убил пытаясь проблему решить.
Автор - это редкий случай, когда у программиста получается писать статьи не только для таких же программистов, но и для обычных людей.
Спасибо, Илья, за вашу работу.
Здравствуйте. Подскажите пожалуйста, как можно написать код в данной ситуации:
У меня n количество маленьких картинок и 1 большая. При нажатии на любую из маленьких картинок, нужно большую убирать, а вместо нее ставить маленькую с уникальным id (в качестве идентификатора, можно использовать название маленькой картинки, 101.jpeg). Этот id нужно присвоить глобальной переменной.
Буду благодарен любым советам.
нагляднее для изучающих было бы выложить весь код "верных" и "неверных" функций, чтоб они у себя в Notepad++ погоняли код, вот, выкладываю этот пример с html- разметкой и кодом JS:
function makeShout() { // (1)
var phrase = "Превед!" // (2)
var shout = function() { // (3,4)
alert(phrase)
}
phrase = "Готово!" // (5)
return shout
}
shout = makeShout()
// что выдаст?
shout()
объясните, пожалуйста, зачем в этом примере мы приравниваем функцию shout к makeShout? Не могу разобраться.
так как всё таки работает Сборщик мусора?
сам алгоритм получение разрешения на удаление Объекта активации ?
(поспешил отправить)
мне кажется многое станет ясно и прозрачно, если будет чёткое понимание алгоритма процесса "уборки мусора".
хотя в разных браузерах это может реализовано по разному.
в Спецификации то же ничего нет.
Можно сделать без замыканий:
Более вариативное решение:
перед тем, как читать дальше, попробуйте этот пример запустить. Online text twist 2 game.
This is a great thing, I think everyone feels this information is very valuable, thank you basketball legends
We provide proper guidance for essay writing, for structure, research, topic help and editing/proofreading. street view
Я люблю учиться, но вот проблема, через пару месяцев или около того вам становится скучно и вы теряете мотивацию ...
Vex 3 - Solitaire
Hmm, I see many new peeps learning it during quarantine thanks a lot.
https://maconhomeimprovements.com/about/
It was a very good post indeed. I thoroughly enjoyed reading it in my lunch time.
Will surely come and visit this blog more often. Thanks for sharing. 먹튀검증
Great article with excellent idea!Thank you for such a valuable article. I really appreciate for this great information.. 직장인대출
This is a very good post .Thanks for letting us know some good tips .
I like your many articles it will help not only me and also many
among us
For your best chat experience with local girls in UK you must to visit shamale manchester
Mature Sex Chat is the best web place for lonley guys in UK to find fine girls for hot chat
Thanks for sharing the information it was very helpful for me candy crush soda
It's really nice and meanful. it's really cool blog. Linking is very useful thing.you have really helped lots of people who visit blog and provide them usefull information. Best dentist in Chico
Thanks for sharing this information. I really like your blog post very much. You have really shared a informative and interesting blog post with people. Toronto Website Design
I discovered your site ideal for me. It consists of wonderful and useful posts. I've read many of them and also got so much from them. In my experience, you do the truly amazing.Truly i'm impressed out of this publish 먹튀검증
Lack of imagination is the result of not reading enough books in childhood. Unblocked game
Roksa kozieglowy
Roksa wieluń
WooDonations is the best woocommerce donations plugin for your store. that use to collect donations on your websites based on WooCommerce. It is a great way to raise funds for NGOs, Charities, and other causes.
That will help you collect online donations using PayPal, Stripe, WooCommerce, other credit card processors, and even cryptocurrency.
Also Check -
woocommerce single product page customizer
woocommerce manage stock
awesome post thanks for sharing check my article here Video Game Stores
aMAZING POST stockfraudnews
Автор - это редкий случай, когда у программиста получается писать статьи не только для таких же программистов, но и для обычных людей.
Спасибо, woodoku Илья, за вашу работу.
Thank you for sharing this awesome post boskizbackyard
Спасибо за полезную информацию nerdle, которой вы поделились octordle, буду следить за ней
awesome post thank you for sharing check my article here asphalt-stars
For your own pleasure find hot ladies from EU exclusive on our web platform sex in linz
the language of the framed 2 and waffle game is very easy to understand. I don't need to look up words from outside websites. A very good article
Your writing is perfect and complete. 바카라사이트 However, I think it will be more wonderful if your post includes additional topics that I am thinking of. I have a lot of posts on my site similar to your topic. Would you like to visit once?
Spend some extratime with sexe trans and enjoy chat with the fine ladies in France
I think about it every time I read your article, but you have a really great insight. Among the people I know online and offline, your insight is at the highest level. That's why I love your blog. I hope you continue to post good comments. 메이저토토사이트
I think about it every time I read your article, but you have a really great insight. Among the people I know online and offline, your insight is at the highest level. That's why I love your blog. I hope you continue to post good comments. 메이저토토사이트
There are a lot of fun, free games available on the internet these days, I usually play flagle because it's great for a lot of people, it feels so much fun when I guess the crossword correctly and get the highest score, are you ready to play? It's so remarkable that I can't help but come across this precious information whenever I surf the internet, thank you very much
Thank you for your post. I have read through several similar topics! However, your article gave me a very special impression, unlike other articles. I hope you continue to have valuable articles like this or more to share with everyone! trap the cat
YouTube Trends is the best website for seeing YouTube trending videos in one place across the world. On YouTube Trends you can watch every category of video like Gaming, Music, Sports, News, Movies, Science & Technology, etc. Pick your favorite one and watch what is trending on youtube today. The list is hourly updated so you can get the latest trending videos on youtube
Область видимости — важная концепция, определяющая доступность переменных. Данная концепция лежит в основе замыканий dinosaur game, разделяя переменные на глобальные и локальные.
I do believe this is an excellent web site. I stumbledupon it ???? I may return yet again since I bookmarked it. Money and freedom is the greatest way to change, may you be rich and continue to help other people. betflikvip
I read good articles and comments here and leave comments with a lot of help. Thank you. I ll grow up and spread good comments. 도파민 접속주소 먹튀폴리스 검증업체를 통해 안전한 카지노사이트
There is no purpose to drawings. You want cartoons to convey a stance and to have an opinion papa's pizzeria
Please let me know if you’re looking for a article writer for your site. You have some really great posts and I feel I would be a good asset. If you ever want to take some of the load off, I’d absolutely love to write some material for your blog in exchange for a link back to mine. Please send me an email if interested. Thank you 바카라사이트 I couldn't think of this, but it's amazing! I wrote several posts similar to this one, but please come and see!!
Top 5 Free Tools for Email Marketing
wordpress template hierarchy
wordpress 6.0.2
how to speed up filezilla ftp transfers
remove wordpress sidebar
wordpress maintenance mode
woocommerce product enquiry form
Если описать концепцию функционального программирования простыми словами, то окажется, что это — подход к программированию, при использовании которого функции можно передавать другим функциям в качестве параметров и использовать функции в качестве значений trap the cat, возвращаемых другими функциями. Занимаясь функциональным программированием, мы проектируем архитектуру приложения и пишем код с использованием функций.
I finally found what I was looking for! I'm so happy. 온라인카지노 Your article is what I've been looking for for a long time. I'm happy to find you like this. Could you visit my website if you have time? I'm sure you'll find a post of interest that you'll find interesting.
hjul
There must have been many difficulties in providing this information. 카지노사이트 Nevertheless, thank you for providing such high-quality information.
The cool things here. I am very satisfied to see. Thank you for your writing. 먹튀폴리스
Your writing is excellent, so allow me to share a little of myself. One of the best available limitless running games is run 3. Control your ball as you compete in a fast ramp race to see how far you can climb the leaderboard.
Spades: Free online card games
This article is a testament to your heardle dedication and hard work, and it really shows in the content of the article. I know you put a lot of effort into this post.
The quality of your writing is exceptional, demonstrating your ovo game language proficiency and understanding of quality sources of knowledge.
Buy gift cards online
Buy gift cards in dollar amounts ranging from $15 to $500. It is easy to check your gift card balance and get gift card help online, and there are no fees or expiration dates to worry about. Usable online or in store, Best Buy Gift Cards and online gift cards are the perfect gift to ensure your friends and family get the gifts on their wish list.
Easy find fine Italian ladies for casual contacts at Ladyboy Genova
Hello, I read the post well. 온라인바카라 It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once
there are several technology blog topics that you can read about technology. In this post, I discuss some thing new.
7 Unique HTML Themes for your business
Free WordPress Plugins For Send WordPress Post Notifications
WordPress Poll Plugin for Contact form 7
7 Ways to Avoid Spam Comments on WordPress
How to use Duplicate Pages and Posts Plugin
What a nice post! I'm so happy to read this. 토토사이트추천 What you wrote was very helpful to me. Thank you. Actually, I run a site similar to you. If you have time, could you visit my site? Please leave your comments after reading what I wrote. If you do so, I will actively reflect your opinion. I think it will be a great help to run my site. Have a good day.
All of the information I’ve gleaned from it basically has been quite useful , and I’d for the most part want to generally commend you on really your abilities, actually contrary to popular belief five nights at freddy's.
They worked on my fnf game browser, thank you for this excellent article
Eine weitere wichtige Funktion von Freemail ist die Möglichkeit, E-Mails von anderen E-Mail-Diensten zu importieren. Dies ist eine nützliche Funktion für Nutzer, die zuvor einen anderen E-Mail-Dienst genutzt haben und ihre alten E-Mails auf ihr neues Freemail-Konto übertragen möchten. Die Plattform unterstützt eine Vielzahl von Formaten, einschließlich IMAP und POP3.
That's a really impressive new idea! 먹튀검증 It touched me a lot. I would love to hear your opinion on my site. Please come to the site I run once and leave a comment. Thank you.
The text gains a human heardle touch with the addition of personal tales and experiences, which makes it more relevant and motivating.
Thank you for the explanation. My website also built with Javascript.
Btw don't forget to visit my blog: blog1
blog2
شركة تسويق الكتروني
استشارات تسويق رقمي اون لاين
جزيل
شركة الدايل
شركة الدايل للسيراميك والرخام والبورسلان
الدايل للسيراميك
الدايل للسيراميك
الحياة السعيدة
رحلات سياحية
برامج سياحية
عروض سفر
هابي لايف
دورات انجليزي
دراسة اللغة الانجليزية
الدراسة في الخارج
Thanks for this article. Fanstatic work Retaining Wall Builder
Precisely what I was looking for, thanks for putting up. 토토사이트
we need work out more techniques in this regard, thanks for sharing. . . . . . 먹튀검증
With havin so much written content do you ever run into any problems of plagorism or copyright violation. 메이저사이트
At this time I am going away to do my breakfast, when having my breakfast coming again to read other news. 먹튀검증
"3D Jewelry Rendering" refers to the process of creating realistic digital representations of jewelry using three-dimensional computer graphics. It involves using specialized software and techniques to simulate materials, lighting, and textures, allowing designers and customers to visualize and evaluate jewelry designs before they are physically produced.
Great job please keep us updated. I am an avid reader on this site.
Blast Rock
I was recommended this blog through a friend from school. No one understood my problem, but I looked at your blog and solved the problem. I will share information about to my friends. I like your blog very much. good luck. 먹튀검증사이트
My curiosity was solved by looking at your writing. Your writing was helpful to me. I want to help you too. 토토사이트 추천
I have been reading your posts regularly. I need to say that you are doing a fantastic job. Please keep up the great work. 메이저사이트 추천
I have joined your rss feed and sit up for seeking extra of your excellent post. Also, I’ve shared your site in my social networks 먹튀검증추천
I all the time emailed this blog post page to all my friends, as if like to read it then my friends will too. 메이저놀이터추천
Great post i must say and thanks for the information. Education is definitely a sticky subject. However, is still among the leading topics of our time. Thanks 안전메이저사이트
Usually keep it up! Nicely i in reality favored analyzing it. This subject supplied by using you could be very practical for proper planning. What’s up, i read your weblog daily. Your writing fashion is 토토사이트
This article provides clear idea designed for the new users of blogging, that truly how to do running a blog. 먹튀사이트
A closure is a function that can access a variable belonging to the scope that contains it (closure function), even when the dino game scope that contains it has finished executing. Specifically, closures can access variables declared in the function that created the closure, even after the function that created it has finished executing.
A closure is a function that can access a variable belonging to the scope that contains it (closure function), even when the dino game scope that contains it has finished executing. Specifically, closures can access variables declared in the function that created the closure, even after the function that created it has finished executing.
I learned a lot from your blog, and you can learn more about older video games to have more engaging experiences. I look forward to playing with you in the past! retro games
I have been reading your blog posts for month and its been the greatest thing I am doing in past few months. keep up the good work for sharing the information. pgslot168 login" title="pgslot168 login">pgslot168 login
Good post, thanks for sharing.. very useful for me, I will bookmark this for my future needs. I would like to thank you for the efforts you have made in writing this article and I am hoping the same best work from you in the future as well. ยูฟ่า168
ufabet168 ทางเข้า เว็บตรง เสถียร ใช้งานง่ายที่สุด
Pretty nice post. I just stumbled upon your blog and wished to say that I have really enjoyed surfing around your blog posts. After all I’ll be subscribing to your feed and I hope you write again very soon! เบทฟิกvip
Thank you for sharing this intriguing article; I value your contribution. the amazing digital circus
I’m pretty pleased to discover this site. I wanted to thank you for your time just for this fantastic read!! I definitely really liked every bit of it and i also have you saved as a favorite to check out new stuff on your site. bio gaming
I'm thankful for your thoughtfulness in sharing this interesting read. jumping shell
Closures in programming are a powerful concept often used in languages that support functional programming suika game paradigms or have functional aspects.
KinitoPET is an exciting and addictive dice game that combines luck and strategy. Players roll dice to achieve specific combinations and earn points. The goal is to score the highest possible total and beat opponents. With its simple rules and dynamic gameplay, KinitoPET offers endless fun for all ages.
الرئيسية
مكتب سفريات
مكتب حجز تذاكر طيران
رحلات بحرية
رحلات كروز
استخراج تاشيرات
عروض سياحية
عروض سياحية
عروض سفر
بكجات سفر اوروبا
عروض سياحة داخلية
رحلات عائلية
رحلات عائلية
رحلات جماعية
دول سياحية رخيصة للعوائل
رحلات
شهر العسل
عروض شهر عسل
بكجات شهر العسل لشخصين
اسعار رحلات شهر العسل
رحلات كروز
رحلات كروز
رحلة كروز
رحلات بحرية
سفينة الكروز
الكروز
دراسة بالخارج
الدراسة بالخارج
مكاتب تقديم الدارسة بالخارج
السفر للدراسة
سياحة علاجية
سياحة علاجية
شركات السياحة العلاجية في السعودية
سفر للعلاج
THE ONE CARGO บริการ นำเข้าสินค้าจากจีน โดยใช้เวลาการขนส่ง 4-6 วันโดยประมาณ การบริการของเราจึงเหมาะสำหรับลูกค้าทั้งรายย่อยและรายใหญ่ ไม่ว่าคุณจะสั่งสินค้าแค่เพียงเล็กน้อย จำนวนไม่กี่กระสอบ ก็มีเรทราคาสำหรับขนส่งจำนวนน้อยให้ หรือถ้าคุณเป็นร้านค้าที่ทำการสั่งของจำนวนมาก ก็มีเรทราคาและบริการสำหรับการขนส่ง
я вообще применил работу этого скрипта в играх слово пацана, можете сами глянуть. Работает феноменально.
Понимание замыканий, безусловно, является ключевым понятием в программировании на JavaScript! Поначалу это может быть сложно, но освоить это будет полезно. Из интересных задач, пробовали ли вы VR-игру Monkey Mart? Управление собственным магазином и удовлетворение потребностей клиентов требует некоторых навыков быстрого мышления и решения проблем, точно так же, как и решение замыканий в JavaScript!
I am always searching online for articles that can help me. There is obviously a lot to know about this. I think you made some good points in Features also. Keep working, great job! เว็บจ่ายไว
Moi c'est ça que j'adore !
ufabet auto เว็บแทงบอลราคาดี มีคู่บอลเปิดให้แทงมากที่สุด บาคาร่า อันดับ1 ศูนย์รวมเกมพนันทุกเกม สมัครง่าย ไม่มีขั้นต่ำ
เว็บออนไลน์ 789 เว็บแทงบอลราคาดี มีคู่บอลเปิดให้แทงมากที่สุด บาคาร่า อันดับ1 ศูนย์รวมเกมพนันทุกเกม สมัครง่าย ไม่มีขั้นต่ำ
Absolutely agree! Having the right pair of eyeglasses not only enhances your vision but also elevates your style. For the Best Online Glasses in Pakistan and to Buy Original Affordable Sunglasses, visit our website and explore our extensive collection of frames and lenses. Proper eye care is essential for clear vision for years to come.
Thank you for this enlightening blog post!
Check out my website - best destination: 包養
The content discusses the powerful yet often misunderstood concept of closures in JavaScript. While closures can pose challenges, they also offer remarkable advantages when wielded correctly. Much like in the online game Monkey Mart, where strategic management maximizes profits, understanding closures allows developers to manage their code with efficiency and precision. Embracing closures can lead to cleaner, more effective programming, similar to how players optimize their resources in the game. Understanding this can transform potential pitfalls into powerful tools, enhancing one's coding experience.
THE ONE CARGO ผู้ให้บริการ คาร์โก้ นำเข้าสินค้าจากจีน เป็นมืออาชีพด้านการนำเข้าสินค้าและพัสดุจัดส่งจากประเทศจีนมาไทย อย่างครบถ้วนปลอดภัย พร้อมเป็นที่ปรึกษา ให้คำแนะนำที่เป็นประโยชน์ต่อลูกค้า เรามีทีมงานพร้อมให้บริการลูกค้าอย่างครบวงจร เป็นตัวแทนนำเข้าสินค้าจากประเทศจีน ให้ช่วยเหลือด้านการค้นหาสินค้าที่ลูกค้าต้องการนำเข้า
The content explores closures in JavaScript, highlighting their dual nature: challenging yet powerful when mastered. Similar to Monkey Mart where strategic management boosts profits, understanding closures empowers developers to efficiently manage code. Embracing closures enhances programming, akin to optimizing resources in the game. This transformation turns coding pitfalls into potent tools, enriching the coding journey.
A waterspout is similar to a tornado
EVO娛樂城
AF娛樂城
EVO娛樂城
Good day! This post couldn’t be written any better! Reading this post reminds me of my old room mate! He always kept talking about this.
Jasa Pengacara Jabodetabek
Good day! This post couldn’t be written any better! Reading this post reminds me of my old room mate! He always kept talking about this.
Jasa Pengacara Jabodetabek Pengacara Perceraian
THE ONE CARGO ชิปปิ้ง จีนคุณภาพ ที่ผู้ประกอบการไว้ใจ บริการนำเข้าสินค้าจากจีนมาไทย ส่งเร็วได้มาตรฐาน เปิดบริการทุกวัน นำเข้าสินค้าจากจีน เอกสารครบถ้วนถูกต้อง ใบขน ใบกำกับ ใบ Form E ขนส่งทางรถ ระยะเวลา 3-5 วัน
explore the intersection of satta the potential implications for the industry
indian matka is a game of chance where players bet on numbers
Замыкание в JavaScript – мощный инструмент, который часто недооценивают, как неподходящая тема для беседы на Omegle. Хотя замыкания могут вызвать проблемы, при правильном понимании они открывают множество возможностей для создания эффективного кода. Осваивая замыкания, вы можете улучшить свои навыки программирования, а также сделать взаимодействие более увлекательным, даже на таких платформах, как Omegle.
Отправить комментарий
Приветствуются комментарии:Для остальных вопросов и обсуждений есть форум.