использование замыкания
Такой вот вопрос
var a; function getA() { if (typeof(a) == 'undefined') { a = 1 + 1; } return a; } var b = getA(); var c = getA(); Можно ли в сделать то же самое но не объявляя переменную 'а' в глобальной области? Ну и чтоб а вычислялось 1 раз. |
Что вы хотите этим сделать?
|
Можно. Вариантов несколько. Только приведенный Вами пример говорит о бесполезности этого. На самом деле это может быть весьма полезным для создания единственного экземпляра объекта - фабрика объектов.
|
Учи основы!!! На сайте куча интересного, полезного, написанного доступным языком материала!
function getA(){ var a = 1+1; return a; } var b = getA(), c = getA(); |
Skipp,with-love-from-siberia,
я хочу вычислять значение один раз. которое буду использовать with-love-from-siberia, Цитата:
|
Sweet,
Спасибо за В'аш совет. Только вот код написанный после В'ашего совета проблему не решает. Я ведь правильно понял, В'ы предложили решение? |
var getA = (function() { var a; return function getA() { if (typeof(a) == 'undefined') { a = 1 + 1; } return a; }; })(); var b = getA(); var c = getA(); |
Riim,
Спасибо! То что нужно! |
Цитата:
Вот еще: function getA() { if ( typeof arguments.callee.a == 'undefined') { arguments.callee.a = 1 + 1; } return arguments.callee.a; }; alert(getA()); alert(getA()); |
Цитата:
UPD: Есть еще такой вариант: function getA(){ return 1+1; };:) |
with-love-from-siberia, в теме есть про замыкания, но да, тоже вариант.
|
Цитата:
|
Цитата:
|
Sweet,
Рад что мы поняли друг друга! |
А так не проще ли?
var getA = (function(){ var a = 1 + 1; return a; })(); var b = getA;Или так? var getA = 1 + 1; var b = getA; |
Цитата:
А это и было одним из условий вопроса |
getA будет по-любому торчать в глобальной области. Я просто не могу понять, почему так важно, чтобы она была функцией, возвращающей значение "а", а не самой "а":)
|
Цитата:
|
Все, вопросов больше не имею. Тогда вариант Riim'а действительно то, что надо.
|
Sweet,
Гут! ) |
Sweet,
Ксати, буду признателен, ели вы всеже отредактируете сообщение за которое я вам поставил минус |
with-love-from-siberia,
спасибо! |
Цитата:
|
Sweet,
ответил в личку |
Лучше так
function getA() { var a = 1 + 1; getA = function() { return a; }; return a; } |
:blink:
Интересный вариант... |
Kolyaj, поделитесь - чем лучше?
|
Kolyaj,
Спасибо! Круто! with-love-from-siberia, На мой взгляд не то что лучше, но более красивый или простой чтоли... |
В примере от Kolyaj создается один scope, потому что выполняется всегда 1 функция, а не две. Меньший расход памяти.
|
Цитата:
|
Маленький коментарий. "никаких проверок не производится" потому что функция переопределена на возвращение конкретного вычисленного ранее значения.
|
B~Vladi,Kolyaj,
inGray, более веские аргументы! + всем! Спасибо! |
Цитата:
Цитата:
В любом случае способ отличный, но далеко не везде можно применять. Беру на заметку:) offtop: Где можно почитать про бинарные операторы? Интересует именно использование их для оптимизации (в том числе и расхода памяти). Желательно с конкретными примерами. |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
Например в самоучителе по C# видел такие строчки: мол бинарные операторы используются в ресурсоёмких программах, вроде перекодировки видео. Сам я честно говоря не вижу в них особой выгоды. Ну да ладно не будем ворошить. В вашей же проблеме: Цитата:
|
Только не бинарные операторы, а побитовые. Бинарные операторы это те, что принимают 2 операнда.
В плане расходов памяти - можно, например, упаковать кучу Boolean'ов в один Number. Можно строки сжимать (хотя тут побитовые операции лишь средство реализации алгоритма). Но в JS реальной нужды, ИМХО, в этом нет и польза микроскопическая. |
Цитата:
Цитата:
B@rmaley.e><e, Пару примеров в студию) |
Могу показать, как упаковать boolean'ы в number.
Вся магия заключается в том, что реально нужен для boolean'а всего 1 (один) бит, но занимает он 8 (?) бит. Можно использовать Number как массив 8 (и более, зависит от размерности типа в битах) Boolean'ов. Пусть для начала n = 0. Это означает, что все boolean'ы по-умолчанию установлены в false. Двоичная форма 0 = 0b00000000. Чтение Чтобы прочитать i-ый (договоримся отсчитывать элементы с конца, нумерация начинается с нуля) символ, используем побитовое И. n & (1 << i)вернет нам 0, если значение в этой ячейке ложно или степень двойки (2^i), если значение истинно. Запись Чтобы записать, например в первую (нумеровать будем с конца) ячейку 1, нужно использовать побитовое ИЛИ, т.е. n = n | 1. Чтобы записать 1 во вторую ячейку, нужно использовать n = n | 2, т.о. для записи 1 в i-ю ячейку используем n = n | (1 << i) n = 0; n |= 1 << prompt('Введите число: '); alert( n.toString(2) ) Чтобы записать туда 0, нужно использовать побитовое И, однако если мы используем тот же прием, что и в предыдущем случае, нас постигнет облом. Но мы сыграем на другом. Если одним из операндов побитового И есть 2^n - 1, т.е. число, в двоичной форме записываемое как набор единиц и только единиц, то результат будет неизменен. Но если хотя бы один "компонент" будет равен нулю, то соответствующее число в результирующем наборе тоже обнулится. Теперь встает вопрос: как получить такой набор? Вспоминаем, что у нас есть такой замечательный унарный оператор как ~! Т.е. нам нужно просто взять 0, записать в нужную позицию 1 и применить побитовое отрицание. var n = parseInt('11011',2), i = prompt('Что будем обнулять?'); n = n & ~(0 | (1 << i)); alert(n.toString(2)); А теперь соберем все это вместе и напишем класс BoolSet. <script type="text/javascript"> function BoolSet(defaultState){ defaultState = defaultState || 0; // при желании тут можно обрабатывать строку или массив this.n = defaultState; } BoolSet.prototype = { get : function(i){ return !!(this.n & (1 << i)); }, set : function(i, value){ if(value = !!value) // 1 this.n |= 1 << i; else // 0 this.n &= ~(0 | (1 << i)); } }; </script> <label> <input type="checkbox" id="val" /> Записать в <input type="number" value="" id="idx-set" />-ый элемент true </label> <input type="button" value="Go!" id="btn-set" /><br/> Получить <input type="number" value="" id="idx-get" />-ый элемент <input type="button" value="Go!" id="btn-get" /><br/> Значение сейчас: <span id="dec-val">0</span> (0b<span id="bin-val">0</span>) <script type="text/javascript"> (function(){ var $ = function(id){return document.getElementById(id)}, boolSet = new BoolSet(0); $('btn-set').onclick = function(){ var i = $('idx-set').value, val = $('val').checked; boolSet.set(i, val); $('dec-val').innerHTML = boolSet.n; $('bin-val').innerHTML = boolSet.n.toString(2); } $('btn-get').onclick = function(){ var i = +$('idx-get').value; alert(boolSet.get(i)); }; }()) </script> P.S. Это писалось по памяти по статье, прочитанной мною более года назад, поэтому где-то (особенно там, где мы записываем 0) я мог ошибиться. |
Как правильно было сказано, значениям типа Boolean достаточно одного бита для представления информации. Следовательно их можно "упаковать" в целочисленный тип.
Если взять, для примера, 32-битные целочисленные переменные, то их можно рассматривать как хранилища 32 булевых значений, где каждый бит - 0 и 1 - соответствует булевым значениям false и true. Такие булевые значения принято называть флагами. Код:
В скобках указаны числа в двоичном формате Код:
Битовое НЕ (ноль - не единица, единица - не ноль) Код:
F_DIRECTORY = 0x0200; |
Часовой пояс GMT +3, время: 21:36. |