Одиночки. В чем разница?
Одиночки.
Есть ли разница и если есть, то в чем она заключается? Раз: var NewObject = {}; (function() { var privateStr = 'Я приватная'; NewObject = { methodX: function() { alert(privateStr); } } }) NewObject.methodX(); Два: var NewObject = new function() { var privateStr = 'Я приватная'; this.methodX = function() { alert(privateStr); } } NewObject.methodX(); |
второй код короче.
но оба бестолковы.. не стоит использовать замыкания для сокрытия состояния объекта. от этого больше неудобств, чем пользы. |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
Просто захотелось. Кстати, а где тогда можно уточнить про влияние таких вот изворотов на скорость скрипта? |
Snipe, экспериментируйте:)
Но мысль на самом деле правильная. В большом проекте лучше скрывать ненужное. Инкапсуляция в ООП для этого и придумана. |
Snipe, посмотрите разницу для обоих случаев в:
alert(NewObject.constructor); // => NewObject.[[prototype]].constructor Поэтому, если говорить об инициализирующем скопе, то первый вариант подойдет больше, т.к. во втором случае получается инстанс анонимной функции. |
Замыкания внутри конструкторов создают скорее не приватные свойства объектов, а приватные статические переменные "классов".И в этой ипостаси, они очень удобны. А городить всё это ради одного свойства, скорее всего, не стоит
|
Цитата:
|
В этом примере не стоит. Если вы приведете другой, тогда можно о нём и поговорить.
|
Естественно данные подходы не нужны для того чтобы спрятать одну функцию. Естественно, что они используются, когда возникает возможность совпадения имен, т.е. при большом количестве скрипта.
На счет стоит-не стоит - пока ни единого разры... тьфу обоснования кроме личных предрасположенностей не встретил. Мне так нравится писать, на мой вгляд если функция не нужна вне, то во вне её быть не должно. Читаемость кода от этого не страдает совсем. Даже наоборот! Есть реальная разница в скорости? Ну или хотябы возможность это проверить? Цитата:
Получается во втором случае инфа хранится дважды? |
есть замечательный скрипт для дампа объекта в целях отладки:
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; } так вот, сокрытие переменных приводит к тому, что мы не можем полноценно отлаживать приложение, ибо не можем получить полное состояние объекта. |
>Естественно, что они используются, когда возникает возможность совпадения имен
Совпадение имён здесь совершенно никаким боком. >Есть реальная разница в скорости? Ну или хотябы возможность это проверить? Да. Описать эту возможность? >обоснования кроме личных предрасположенностей не встретил. Обоснования были даны совершенно чёткие - страдает читабельность кода, скорость скрипта, количество используемой памяти. Замыкания позволяют создать аналог скрытых свойств и перенос напрямую всех подходов из "классового" ООП обычно не приводят ни к чему хорошему. |
Я тоже считаю, что если в JavaScript нету встроенного разделения на private/public, то изворачиваться через закрытие области видимости - кощунство.
Я, например, не могу подобрать задачу, в которой нужно будет скрыть определённые свойства объекта. Обычно это делается либо для защиты (закрытие кода/состояния от внешнего доступа), что актуально в коде "библиотек", либо просто для эстетики, чтоб внутренние действия класса не были наглядны и не мешали пониманию работы. Но если эстетика представления объекта мешает эстетики кода JavaScript, то лучше, всё-таки, на ней не зацикливаться. |
> Извиняюсь, не совсем понял, во втором случае у нас еще остается анонимная функция,
Да. Еще раз: первый подход вполне уместен (и именно для обеспечения того, чтобы не засорять глобальный объект), когда речь идет об инициализации, и внутри этой инициализации используются вспомогательные локальные var'ы. Скоп этой "singleton'ной" функции будет доступен внутренним замыканиям и, как следствие, свойствам иницализируемого объекта. Но в отличии от второго случая, функция не будет жить дальше (во втором - будет - и зачем это надо? Поэтому первый способ - предпочтительней). Цитата:
|
А где в примере из первого поста singleton? В моём преставлении этот паттерн реализуется в виде метода, возвращающего ссылку на экземпляр класса. Или я не прав? Хотя зачем такое в JavaScript, тут вообще классов по сути нету.
|
такой подход не может быть уместен, ибо все методы создаются заново при каждом инстанцировании объекта.
|
Цитата:
Скорость определения замкнутых 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()); |
Цитата:
Цитата:
Цитата:
Я тоже могу сказать, что IE со строками работает быстрее других браузеров, однако это только слова, надо их чем-то подкрепить (правда в моем случае нечем :) ). По поводу читаемости и эстетики, если у вас используется несколько JS файлов, отдельно для комментариев, отдельно для меню и пр., можете поверить на слово, без инкапсуляции код будет читаться гораздо сложнее чем с (можете, правда, и не поверить). Вполне допускаю, что будет несколько функций с одинаковыми именами. И чем больше проект, тем сложнее будет слдеить за отсутствием повторов. А если использовать библиотеки со стороны, у которых тоже все функции вывалены прям так... Так что предлагаю тему читаемоости закрыть сразу и больше к ней не возвращаться. Делали - читаемо. :) Цитата:
Вот это я понимаю тема, интересно обсудить, а то все "как сделать, чтоб onclick работал?" :) Продолжаем разговор. |
Цитата:
|
Цитата:
|
Snipe,
По моему личному опыту, самый читабельный ОО код (в JavaScript) - когда весь объект представлен одним хэшем. Хотя из-за проблемы с запятыми, такой вид не очень удобен. |
|
не надо путать сокрытие полей с инкапсуляцией.
первое - не имеет никакого смысла, особенно в динамических языках, коим и является яваскрипт. конфликты имён решаются элементарно посредством неймспейсов. при использовании замыканий для сокрытия приходится увеличивать число отступов у вложенных блоков. при количестве отступов > 3, код становится трудночитаем. |
tenshi, не знаю, у меня используются замыкания для сокрытия и число отступов очень мало где превышает 3.
Читаемость -- тема отдельной беседы. Кто-то например может ставить фигурные скобки в микрософтовском стиле, а лично мне такой код нечитабелен. |
это пока у тебя скрипты маленькие...
|
tenshi, конечно, маленькие -- каждый обьект в своем файле.
|
Цитата:
Читабельность, конечно, вопрос индивидуальный, но мне комфортней var f = function() {}; f.prototype = { m1: function() {}, m2: function() {}, m3: function() {} };чем var f = function() { this.m1 = function() {}; this.m2 = function() {}; this.m3 = function() {}; } |
Kolyaj, а если обьект библиотечный и создается в одном экземпляре? Конечно, в контролах замыкания лучше не использовать.
|
Цитата:
var Singleton = { init: function() {}, m1: function() {}, m2: function() {} }; Singleton.init(); Тут я вообще не вижа смысла городить конструкцию вида var Singleton = new (function() { ... })()ибо лишняя цепочка прототипов |
Kolyaj, ну, лично мне тоже вторая запись не очень нравится. Но пока мы с вами не работаем над одним проектом, какая разница?
|
hogart, что, и вложенных объектов нет?
|
tenshi, стараемся не делать.
|
ага! стараемся, но всё-таки бывают?
|
tenshi, я поищу сегодня, если будет время. Навскидку не помню. Но JS к проекту писало как минимум три человека, там всякое бывает:)
Как минимум есть анонимные хэши, предназначенные для передачи параметров. Это считово?:) |
всё считается, что порождает отступы :-)
|
tenshi, ну, хэш с параметрами обычно пишется как-нить так:
{userid: this.userid, name: this.name} Обходимся без отступов:) еще раз поясню: наша архитектура такова, что каждый законченный кусок функциональности умещается в одном файле, кои файлики подгружаются по надобности. Можете походить по ярушке с firebug'ом наголо и поглядеть, как оно там все устроено «внутре, где у нея неонка». |
Цитата:
|
Часовой пояс GMT +3, время: 14:36. |