02.06.2008, 17:54
|
|
Профессор
|
|
Регистрация: 06.05.2008
Сообщений: 765
|
|
Сообщение от vasa_c
|
А городить всё это ради одного свойства, скорее всего, не стоит
|
Никто не говорил что оно одно, это просто пример. Или мы о разном?
|
|
02.06.2008, 18:05
|
|
Профессор
|
|
Регистрация: 12.03.2008
Сообщений: 183
|
|
В этом примере не стоит. Если вы приведете другой, тогда можно о нём и поговорить.
|
|
02.06.2008, 18:31
|
|
Профессор
|
|
Регистрация: 06.05.2008
Сообщений: 765
|
|
Естественно данные подходы не нужны для того чтобы спрятать одну функцию. Естественно, что они используются, когда возникает возможность совпадения имен, т.е. при большом количестве скрипта.
На счет стоит-не стоит - пока ни единого разры... тьфу обоснования кроме личных предрасположенностей не встретил.
Мне так нравится писать, на мой вгляд если функция не нужна вне, то во вне её быть не должно.
Читаемость кода от этого не страдает совсем. Даже наоборот!
Есть реальная разница в скорости? Ну или хотябы возможность это проверить?
Сообщение от Dmitry A. Soshnikov
|
Поэтому, если говорить об инициализирующем скопе, то первый вариант подойдет больше, т.к. во втором случае получается инстанс анонимной функции.
|
Извиняюсь, не совсем понял, во втором случае у нас еще остается анонимная функция, которой в первом случае нет?
Получается во втором случае инфа хранится дважды?
Последний раз редактировалось Snipe, 02.06.2008 в 18:36.
|
|
02.06.2008, 18:58
|
Профессор
|
|
Регистрация: 20.03.2008
Сообщений: 1,183
|
|
есть замечательный скрипт для дампа объекта в целях отладки:
function dump( obj ){
var pairs= [];
var blocked= [];
if( obj ) for( var key in obj ){
try{
pairs.push( key + ': ' + obj[ key ] );
} catch( e ){
blocked.push( key );
}
}
if( pairs ) obj+= ' {', pairs.join(', '), '}';
if( blocked ) obj+= '[blocked: ' + blocked.join(', ') + ' ]';
return obj;
}
так вот, сокрытие переменных приводит к тому, что мы не можем полноценно отлаживать приложение, ибо не можем получить полное состояние объекта.
__________________
.ня
Последний раз редактировалось tenshi, 02.06.2008 в 19:01.
|
|
02.06.2008, 19:13
|
|
Профессор
|
|
Регистрация: 12.03.2008
Сообщений: 183
|
|
>Естественно, что они используются, когда возникает возможность совпадения имен
Совпадение имён здесь совершенно никаким боком.
>Есть реальная разница в скорости? Ну или хотябы возможность это проверить?
Да. Описать эту возможность?
>обоснования кроме личных предрасположенностей не встретил.
Обоснования были даны совершенно чёткие - страдает читабельность кода, скорость скрипта, количество используемой памяти.
Замыкания позволяют создать аналог скрытых свойств и перенос напрямую всех подходов из "классового" ООП обычно не приводят ни к чему хорошему.
|
|
02.06.2008, 19:29
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
Я тоже считаю, что если в JavaScript нету встроенного разделения на private/public, то изворачиваться через закрытие области видимости - кощунство.
Я, например, не могу подобрать задачу, в которой нужно будет скрыть определённые свойства объекта. Обычно это делается либо для защиты (закрытие кода/состояния от внешнего доступа), что актуально в коде "библиотек", либо просто для эстетики, чтоб внутренние действия класса не были наглядны и не мешали пониманию работы. Но если эстетика представления объекта мешает эстетики кода JavaScript, то лучше, всё-таки, на ней не зацикливаться.
Последний раз редактировалось Андрей Параничев, 02.06.2008 в 21:27.
|
|
02.06.2008, 21:29
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
> Извиняюсь, не совсем понял, во втором случае у нас еще остается анонимная функция,
Да.
Еще раз: первый подход вполне уместен (и именно для обеспечения того, чтобы не засорять глобальный объект), когда речь идет об инициализации, и внутри этой инициализации используются вспомогательные локальные var'ы.
Скоп этой "singleton'ной" функции будет доступен внутренним замыканиям и, как следствие, свойствам иницализируемого объекта. Но в отличии от второго случая, функция не будет жить дальше (во втором - будет - и зачем это надо? Поэтому первый способ - предпочтительней).
Сообщение от vasa_c
|
>Есть реальная разница в скорости? Ну или хотябы возможность это проверить?
Да. Описать эту возможность?
|
А о каких скоростях идет речь? Первого и второго подходов? А что за возможность? =)
|
|
02.06.2008, 21:42
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
А где в примере из первого поста singleton? В моём преставлении этот паттерн реализуется в виде метода, возвращающего ссылку на экземпляр класса. Или я не прав? Хотя зачем такое в JavaScript, тут вообще классов по сути нету.
Последний раз редактировалось Андрей Параничев, 02.06.2008 в 21:56.
|
|
02.06.2008, 22:18
|
Профессор
|
|
Регистрация: 20.03.2008
Сообщений: 1,183
|
|
такой подход не может быть уместен, ибо все методы создаются заново при каждом инстанцировании объекта.
__________________
.ня
|
|
02.06.2008, 22:25
|
Профессор
|
|
Регистрация: 25.02.2008
Сообщений: 707
|
|
Сообщение от Андрей Параничев
|
Или я не прав?
|
Прав =) Более того, даже и второй случай синглтоном (в понимании паттерна при классовом ООП) нельзя считать (в том плане, что даже и нет возможности повторно обратиться к "классу", чтобы он вернул тот же инстанс). Просто данную конструкцию - (function() { ... __init__(); ... })(); - иногда называют (инициализирующим) синглтоном. И в ключе использования вспомогательных инициализирующих var'ов и локальных функций (именно для этого и выделяется локальный скоп этой анонимной функции, которая запустится единожды и исчезнет (если, конечно, не будет ссылок на нее), хотя, скоп ее останется)) - вполне удобно.
Скорость определения замкнутых var'ов, естественно, будет медленнее, т.к. они находятся не в родном скопе (в смысле, return this.a будет быстрее, чем return a, где a - локальный замкнутый var).
А подобие (имитация) классического паттерна могла бы выглядеть, например, так:
function SingletonClass() {
}
SingletonClass.getInstance = function() {
if (!SingletonClass.instance) {
SingletonClass.instance = new function() {
this.a = 10;
return true;
};
SingletonClass.instance.getA = function() {
return this.a;
};
SingletonClass.instance.setA = function(a) {
this.a = a;
return true;
};
}
return SingletonClass.instance;
};
var a = SingletonClass.getInstance();
a.setA(20);
var b = SingletonClass.getInstance();
alert(b.getA());
Последний раз редактировалось Dmitry A. Soshnikov, 02.06.2008 в 22:42.
|
|
|
|