Comments 86
Да, спасибо. Пользовался этим и даже не знал как оно называется. А вот создание тру-приватных свойств очень даже интересно и познавательно.
Это не совсем тру-приватные свойства, но очень близко к ним.
Обширная статья — побольше бы таких
Только приватные переменные можно достать следующим образом:
var MyModule = (function() {
var field = 'Habrahabr';
return {
sayPrevedToHabrahabr: function() {
alert(field);
}
}
})();
MyModule.sayPrevedToHabrahabr(); //alerts «PREVED Habrahabr»
// получение псевдо-приватного поля
var private_var;
eval('private_var=field', MyModule.sayPrevedToHabrahabr);
alert(private_var);
Только приватные переменные можно достать следующим образом:
var MyModule = (function() {
var field = 'Habrahabr';
return {
sayPrevedToHabrahabr: function() {
alert(field);
}
}
})();
MyModule.sayPrevedToHabrahabr(); //alerts «PREVED Habrahabr»
// получение псевдо-приватного поля
var private_var;
eval('private_var=field', MyModule.sayPrevedToHabrahabr);
alert(private_var);
Думаю еще будут полезными ссылки на статью Мартина Фаулера о замыканиях вообще (на англ.) martinfowler.com/bliki/Closure.html и Нила Гафтера об истории возникновения замыканий (тоже на англ.) gafter.blogspot.com/2007/01/definition-of-closures.html
Кстати, узнав впервые что такое замыкания я наконец-то понял зачем в Java нужны inner classes.
За статью спасибо, кроме самих замыканий интересно было узнать и про управление доступом в Javascript. На досуге почитаем поподробнее, занятная тема вообще
Кстати, узнав впервые что такое замыкания я наконец-то понял зачем в Java нужны inner classes.
За статью спасибо, кроме самих замыканий интересно было узнать и про управление доступом в Javascript. На досуге почитаем поподробнее, занятная тема вообще
хорошая статья, спасибо
Скоро ещё выйдет книга в которой все эти вещи будут описаны «Secrets of the JavaScript Ninja» John Resig
Вот примеры нескольких глав из книги:
How closures work — ajaxian.com/downloads/books/javascriptninja/JavaScriptNinja_ch3_Article1.pdf
Using (function(){})() — ajaxian.com/downloads/books/javascriptninja/JavaScriptNinja_ch3_Article2.pdf
Class-Like Code — ajaxian.com/downloads/books/javascriptninja/JavaScriptNinja_ch5_Article2.pdf
Вот примеры нескольких глав из книги:
How closures work — ajaxian.com/downloads/books/javascriptninja/JavaScriptNinja_ch3_Article1.pdf
Using (function(){})() — ajaxian.com/downloads/books/javascriptninja/JavaScriptNinja_ch3_Article2.pdf
Class-Like Code — ajaxian.com/downloads/books/javascriptninja/JavaScriptNinja_ch5_Article2.pdf
Замыкания — одно из самых сложных для понимания вещей, особенно для начинающих.
Спасибо за хороший материал с объяснениями.
4 абзац, видимо опечатка — «остаются доступными внутренней функцией функции»
Спасибо за хороший материал с объяснениями.
4 абзац, видимо опечатка — «остаются доступными внутренней функцией функции»
Очень хорошая статья.
Хотелось бы добавить, что иногда замыкания могут послужить причиной мемори-ликов. Например в коде:
Хотя и
Вот более живой пример:
Как с этим бороться можно почитать тут на английском.
Хотелось бы добавить, что иногда замыкания могут послужить причиной мемори-ликов. Например в коде:
function createHelloFunction = function(name) { var myBigObject = createSomeBigObject(); return function() { alert('Hello, ' + name); } } var sayHelloHabrahabr = createHelloFunction('Habrahabr');
Хотя и
myBigObject
в возвращаемой функции не используется, ссылка на него остаётся (по крайней мере покуда жив sayHelloHabrahabr
). Вот более живой пример:
function attach() { var element = document.getElementById("my-element"); element.attachEvent("onclick", function(){ alert("Clicked: " + element.innerHTML); }); }
Как с этим бороться можно почитать тут на английском.
Язык JS к сожалению хренова описан.
Что в нем есть замыкания( точнее что их тама можно написать ) я узнал только год назад, а что они есть в php так и всего пару месяцев как.
А вот годика 3 назад я познакомился в замыканиями в lua.
Это была жесть. Мы сидели всем офисом и медитировали.
На выходе часто получался код которые непонятно как, но работает
Потом привыкли, выучили страшные слова типа лямда-функция, узнали что «клошуре» это не «калоша» а «замыкание» ( уж не знаю почему 5 человек год даже не пытались перевести термин на русский)
Но всеже не спешим использовать замыкания и другие фокусы повсеместно.
— Приходят на работу люди сразу после института и начинаются «тупняк»
Не учат этой уличной магии в институте.
В указаных примерах магии особо нет, но если постараться ее можно придумать. Так вот — лучше не придумывайте. Морда проше — и люди потянутся
А изучившим магию бууста замыкания уже… поздно, человек уже сам замкнулся, не мыт, не брит… работает программист! отойдите! и не подкармивайте!
это опасно, может привязаться
Что в нем есть замыкания( точнее что их тама можно написать ) я узнал только год назад, а что они есть в php так и всего пару месяцев как.
А вот годика 3 назад я познакомился в замыканиями в lua.
Это была жесть. Мы сидели всем офисом и медитировали.
На выходе часто получался код которые непонятно как, но работает
Потом привыкли, выучили страшные слова типа лямда-функция, узнали что «клошуре» это не «калоша» а «замыкание» ( уж не знаю почему 5 человек год даже не пытались перевести термин на русский)
Но всеже не спешим использовать замыкания и другие фокусы повсеместно.
— Приходят на работу люди сразу после института и начинаются «тупняк»
Не учат этой уличной магии в институте.
В указаных примерах магии особо нет, но если постараться ее можно придумать. Так вот — лучше не придумывайте. Морда проше — и люди потянутся
А изучившим магию бууста замыкания уже… поздно, человек уже сам замкнулся, не мыт, не брит… работает программист! отойдите! и не подкармивайте!
это опасно, может привязаться
читал раньше здесь:
javascript.ru/tutorial/basic/closure#prostoie-opisaniie
javascript.ru/tutorial/basic/closure#prostoie-opisaniie
Если честно, мне кажется что автор несколько… перемудрил, что-ли. Если человек без достаточного опыта посмотрит на статью, то он просто — напросто может испугаться яваскрипта, заплакать и убежать. И тогда не исключено, что страна, да и весь мир, может потерять потенциального гениального программиста.
Короче, к чему я это: если это статья расчитана не только на опытных разработчиков, но и на относительно начинающих, постарайтесь приводить более простые в понимании примеры.
ИМХО неплохая статья для понимания смысла замыканий в JS лежит вот здесь — javascript.ru/tutorial/basic/closure
Короче, к чему я это: если это статья расчитана не только на опытных разработчиков, но и на относительно начинающих, постарайтесь приводить более простые в понимании примеры.
ИМХО неплохая статья для понимания смысла замыканий в JS лежит вот здесь — javascript.ru/tutorial/basic/closure
Не знаю, не знаю… Я например JS всего месяца 4 изучаю и то от случая к случаю, однако статья меня совсем не напугала, а наоборот очень заинтересовала. Лично для меня она приоткрывает настоящий JS, а не просто средство для выпадающих менюшек и прочих украшательств.
Речь про то, что человек может начинать вообще изучение программирования (школьные годя чудесные не берем) с JS. Были же у многих цепочки такого рода: HTML -> JS -> PHP/Perl/ASP и т.д.
В таком случае эта статья его напугать может. ИМХО статья такого рода намного ценнее, если она пригодна наиболее широкой массе читателей, а не только тем, кто достиг относительно неплохого уровня.
В таком случае эта статья его напугать может. ИМХО статья такого рода намного ценнее, если она пригодна наиболее широкой массе читателей, а не только тем, кто достиг относительно неплохого уровня.
О! Прошу прощения, только сейчас заметил, что линк уже был дан постом выше.
Да, по этой ссылке — тоже хорошая статья.
Мне просто хотелось написать более-менее исчерпывающую и практичную статью по данному предмету, чтобы дать человеку возможность разобраться в нём основательно, узнав не только про то, что это такое и как выглядит, но и про то, как именно это используют в современной веб-разработке.
Мне просто хотелось написать более-менее исчерпывающую и практичную статью по данному предмету, чтобы дать человеку возможность разобраться в нём основательно, узнав не только про то, что это такое и как выглядит, но и про то, как именно это используют в современной веб-разработке.
все-таки не
function createHelloFunction = function(name) {
а
var createHelloFunction = function(name) {…
Ну и для сохранений между вызовами проще использовать func_name.attr типа
function countIt(reset) {
if (reset ||! countIt.cnt) countIt.cnt = 0;
return countIt.cnt++;
}
function createHelloFunction = function(name) {
а
var createHelloFunction = function(name) {…
Ну и для сохранений между вызовами проще использовать func_name.attr типа
function countIt(reset) {
if (reset ||! countIt.cnt) countIt.cnt = 0;
return countIt.cnt++;
}
Замыкания все-таки удобней
function countlt(reset) {
var cnt = 0;
countlt = function(reset) {
if (reset) cnt = 0;
return cnt++;
};
return countlt(reset);
}
function countlt(reset) {
var cnt = 0;
countlt = function(reset) {
if (reset) cnt = 0;
return cnt++;
};
return countlt(reset);
}
и чем это удобней? Кода больше — смысл тот же. Опять же про утечки думать надо.
Замыкания очень приятная штука, но все ж не надо их вставлять там, где они не нужны.
Замыкания очень приятная штука, но все ж не надо их вставлять там, где они не нужны.
Какие утечки? Если вы переменную будете хранить в свойстве, а не внутри функции, она меньше места от этого занимать не будет. Плюс недоступность переменной извне (для эстетов).
я храню переменную, а вы — переменную И функцию.
вот тут уже написали habrahabr.ru/blogs/webdev/38642/#comment_919147
вот тут уже написали habrahabr.ru/blogs/webdev/38642/#comment_919147
Ну во-первых, не функцию, а ее скоп. Во-вторых, где же тут утечка? Утечка — это когда в памяти лежит что-то, что не используется, в моем примере все используется. Ну и в-третьих, пример слишком простой, чтобы о нем спорить.
Данный подход полезен, когда в функции нужно выполнять кучу условий, параметры которых не меняются в течение работы скрипта (обеспечение кроссбраузерности, например). Вот здесь script.shabunc.org/? p=33 хорошо описано.
Данный подход полезен, когда в функции нужно выполнять кучу условий, параметры которых не меняются в течение работы скрипта (обеспечение кроссбраузерности, например). Вот здесь script.shabunc.org/? p=33 хорошо описано.
Поправил, спасибо.
Насчёт сохранения — ну это дело вкуса, кому что больше нравится. Мне скажем не нравится такой подход во-первых потому, что аттрибут можно легко подменить — переменные замыкания лучше изолированы от внешнего воздействия, а во-вторых потому, что для независимости от имени функции в вашем случае приходится писать arguments.callee.attr везде, а это куда менее красиво, чем просто attr в случае замыкания.
Насчёт сохранения — ну это дело вкуса, кому что больше нравится. Мне скажем не нравится такой подход во-первых потому, что аттрибут можно легко подменить — переменные замыкания лучше изолированы от внешнего воздействия, а во-вторых потому, что для независимости от имени функции в вашем случае приходится писать arguments.callee.attr везде, а это куда менее красиво, чем просто attr в случае замыкания.
В который раз замечаю что javascript не так прост, как кажется на первый взгляд. Спасибо.
Хорошо )
Спасибо большое, занес в избранное :)
Понравилось, спасибо.
Добавил в избранное.
Добавил в избранное.
Замыкания в Си :)
lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html
lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html
Javascript вскоре станет полноценным объектно-ориентированным языком. Здорово!
не станет, пока! Новая версия стандарта придерживается той же идеологии. ECMAScript драфт 4, который ООП-style, не приняли. Недавно весь инет гудел по этому поводу.
Ну вообще-то разработчики ECMAScript Harmony пока что не решили этот вопрос до конца — вполне возможно, что там будут фичи на уровне языка для классической модели ООП, просто в упрощенном варианте.
Вот здесь об этом можно почитать: ejohn.org/blog/ecmascript-harmony/
Вот здесь об этом можно почитать: ejohn.org/blog/ecmascript-harmony/
я ж и не говорил, что до конца. Факт в том, что новая версия стандарта принята, и в этой версии идеология таже.
en.wikipedia.org/wiki/Prototype-based_programming
Далее покупаем книжки «Structure and Interpretation of Computer Programs» и «Concepts, Techniques, and Models of Computer Programming», укладываем мысли в порядок и не обращаем внимания на «программистов» без образования…
Далее покупаем книжки «Structure and Interpretation of Computer Programs» и «Concepts, Techniques, and Models of Computer Programming», укладываем мысли в порядок и не обращаем внимания на «программистов» без образования…
Боже, упаси!
Возник вопрос. Зачем яваскриптовый интерпритатор сохраняет и не очищает память от неиспользуемых объектов? (либо я не правильно понимаю)
Рассмотрим простой синтетический пример
function createFunction = function() {
// много очень тяжелых объектов, которые много памяти съедают
var obj1 = new Obj1();
var obj2 = new Obj2();
var obj3 = new Obj3();
// Возвращаемое значение
return function(){
alert('Я простая функция, и не использую никакие внутренние объекты');
}
}
// использование
var func = createFunction();
В этом случае хранятся все объекты, которые созданы внутри. Зачем так сделано? Ведь они не используются в самой функции. По сути создается некая сущность, результатом работы которой является простая функция. Интерпритатор это хорошо знает. Для каких целей хранить все остальное в памяти?
Либо, если можно, приведите пример того, как можно воспользоваться внутренними объектами извне? Не уже ли это сделано для того, чтобы дать возможность менять прототип функции и объектная модель при этом не портилась? То есть, чтобы можно было добавить или переобпределить эту самую функцию?… вот, хотелось бы увидеть наглядный пример
Рассмотрим простой синтетический пример
function createFunction = function() {
// много очень тяжелых объектов, которые много памяти съедают
var obj1 = new Obj1();
var obj2 = new Obj2();
var obj3 = new Obj3();
// Возвращаемое значение
return function(){
alert('Я простая функция, и не использую никакие внутренние объекты');
}
}
// использование
var func = createFunction();
В этом случае хранятся все объекты, которые созданы внутри. Зачем так сделано? Ведь они не используются в самой функции. По сути создается некая сущность, результатом работы которой является простая функция. Интерпритатор это хорошо знает. Для каких целей хранить все остальное в памяти?
Либо, если можно, приведите пример того, как можно воспользоваться внутренними объектами извне? Не уже ли это сделано для того, чтобы дать возможность менять прототип функции и объектная модель при этом не портилась? То есть, чтобы можно было добавить или переобпределить эту самую функцию?… вот, хотелось бы увидеть наглядный пример
для подстраховки от таких штук:
return function(){
var str= 'alert(obj1)';
eval( str );
}
return function(){
var str= 'alert(obj1)';
eval( str );
}
Если «я простая функция и не использую никакие внутренние объекты», то зачем мне быть внутри? Значит место моё тоже должно быть простым — снаружи… ну, или внутри функции, не насыщенной так сильно переменным и т.д.
Предполагаю, что garbage collection в современных браузерах достаточно умна, чтобы делать объекты доступными для чистки, если на них в коде не осталось ссылок из замыканий. Но вообще на практике это не так существенно, потому что ситуации, когда замыкание не использует объектов выше, достаточно редкие. А если всё-таки возникают, лишние переменные можно опять же окружить замыканием и вне его они не попадут:
(function() {
var obj1 = new Obj1();
var obj2 = new Obj2();
var obj3 = new Obj3();
})();
return function…
Извне внутренними объектами не нужно пользоваться, они используются внутри функции при формирования результата вызова. Насчёт примера — не совсем понял, какой вам нужен пример кроме тех, что показаны в статье, объясните, пожалуйста.
(function() {
var obj1 = new Obj1();
var obj2 = new Obj2();
var obj3 = new Obj3();
})();
return function…
Извне внутренними объектами не нужно пользоваться, они используются внутри функции при формирования результата вызова. Насчёт примера — не совсем понял, какой вам нужен пример кроме тех, что показаны в статье, объясните, пожалуйста.
(for var i = 0; i < links.length; i++) {
//(function(i) {
var k= i;
links[k].onclick = function() {
alert(k);
}
//})(i);
}
не надо делать двойных замыканий ;-)
//(function(i) {
var k= i;
links[k].onclick = function() {
alert(k);
}
//})(i);
}
не надо делать двойных замыканий ;-)
> (for var i = 0; i < links.length; i++)
Lisp || JS —?
%)
Lisp || JS —?
%)
Во вступительном посте:
Что курил автор?
… js — функциональный язык программирования (не путать с процедурным). Не совсем, конечно, чистый функциональный язык, но основные моменты присутствуют.
Что курил автор?
Ряд свойств. Этого недостаточно, чтобы с ходу в лоб называть язык функциональным )
В таком случае язык называют мультипарадигмальным :)
ru.wikipedia.org/wiki/Мультипарадигмальный язык программирования — там JS причисляют три парадигмы: императивную, функциональную и ОО.
ru.wikipedia.org/wiki/Мультипарадигмальный язык программирования — там JS причисляют три парадигмы: императивную, функциональную и ОО.
Хорошая статья, спасибо! добавлю в избранное и сохраню в копилочку ))
Доступ к переменным не локальной области видимости требует больших затрат… не увлекайтесь замыканиями без надобности… хотя на простеньких задачах, коих большинство это неважно.
Кстати прятать код с локальными переменными и обьектами можно не только в анонимной функции
(function(){
//ваш спрятанный код
}();
но и в анонимном конструкторе обьекта два байта короче :-) и читается легче
new function(){
//ваш спрятанный код
};
точку с запятой не забывайте иначе при сжатии кода могут быть проблемы.
Кстати прятать код с локальными переменными и обьектами можно не только в анонимной функции
(function(){
//ваш спрятанный код
}();
но и в анонимном конструкторе обьекта два байта короче :-) и читается легче
new function(){
//ваш спрятанный код
};
точку с запятой не забывайте иначе при сжатии кода могут быть проблемы.
>Доступ к переменным не локальной области видимости требует больших затрат
Буду рад увидеть ссылку на подтверждающие это бенчмарки. :)
Буду рад увидеть ссылку на подтверждающие это бенчмарки. :)
dev.opera.com/articles/view/efficient-javascript/? page=2#avoidglobal
web.archive.org/web/20071206145017/http://www.jorendorff.com/articles/javascript/speed-test.html
web.archive.org/web/20071206145017/http://www.jorendorff.com/articles/javascript/speed-test.html
> Следующее, принципиально иное применение замыканий — защита данных.
Это называется инкапсуляция.
Спасибо за хорошую статью!
Это называется инкапсуляция.
Спасибо за хорошую статью!
Спасибо за статью очень интересно.
Как Вам такая комбинация?
function some() {
........var self = arguments.callee;
........if(!self.clk) {//Инициализация выполняется только один раз
................self.clk = function() {alert(this.i)}
........}
........for (var i = 0; i < links.length; i++) {
................links[i].onclick = self.clk.bind({i:i})
........}
}
функция self.clk опеределяется один раз для всех
Как думаете, будет ли выигрыш в производительности при таком подходе?
Как Вам такая комбинация?
function some() {
........var self = arguments.callee;
........if(!self.clk) {//Инициализация выполняется только один раз
................self.clk = function() {alert(this.i)}
........}
........for (var i = 0; i < links.length; i++) {
................links[i].onclick = self.clk.bind({i:i})
........}
}
функция self.clk опеределяется один раз для всех
Как думаете, будет ли выигрыш в производительности при таком подходе?
var MyModule = (function() { var name = 'Habrahabr'; function sayPreved() { alert('PREVED ' + name.toUpperCase()); } return { sayPrevedToHabrahabr: function() { sayPreved(name);// [ 8 ] } } })(); MyModule.sayPrevedToHabrahabr();
В 8-й строке (я ее пометил комментом [ 8 ]) вызов ф-ии sayPreved() делается с параметром name.
Это смысловая опечатка или нет (если необходимо, то зачем)? (у меня сработало и с вызовом без параметра)
Спасибо! Очень полезно!
За статью спасибо) Просто и понятно.
Очень хорошая статья — только она смогла боле-менее упорядочить в голове весь бардак, сгенерированный просмотром исходников jQuery.
Кто-нибудь, подскажите, пожалуйста, я не очень понимаю, зачем использовать замыкание для инкапсуляции:
Решил проверить, что пример с sayPrevedToHabrahabr действительно помогает инкапсулировать методы и свойства MyModule.
Для этого создал функцию:
Далее создал объект
и попробовал обратиться к его локальным переменным и методам:
Может быть, локальная функция создалась в глобальной области видимости?
попробовал sayPreved(), но это так же падает с ошибкой.
Зачем же в таком случае использовать замыкания для инкапсуляции данных, если последние и так недоступны из вне?
Решил проверить, что пример с sayPrevedToHabrahabr действительно помогает инкапсулировать методы и свойства MyModule.
Для этого создал функцию:
function MyModule() {
var name = 'Habrahabr';
function sayPreved() {
alert('PREVED ' + name.toUpperCase());
}
this.sayPrevedToHabrahabr = function() {
sayPreved(name);
};
};
Далее создал объект
var myModule = new MyModule();
и попробовал обратиться к его локальным переменным и методам:
document.writeln(myModule.name); // undefined
document.writeln(myModule.sayPreved()); // Uncaught TypeError: undefined is not a function on line 15
Может быть, локальная функция создалась в глобальной области видимости?
попробовал sayPreved(), но это так же падает с ошибкой.
Зачем же в таком случае использовать замыкания для инкапсуляции данных, если последние и так недоступны из вне?
Sign up to leave a comment.
Замыкания в JavaScript