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 —?
%)
UFO just landed and posted this here
Во вступительном посте:
Что курил автор?
… js — функциональный язык программирования (не путать с процедурным). Не совсем, конечно, чистый функциональный язык, но основные моменты присутствуют.
Что курил автор?
UFO just landed and posted this here
Ряд свойств. Этого недостаточно, чтобы с ходу в лоб называть язык функциональным )
В таком случае язык называют мультипарадигмальным :)
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
> Следующее, принципиально иное применение замыканий — защита данных.
Это называется инкапсуляция.
Спасибо за хорошую статью!
Это называется инкапсуляция.
Спасибо за хорошую статью!
UFO just landed and posted this here
Спасибо за статью очень интересно.
Как Вам такая комбинация?
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