Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Организация кода в публичной библиотеке (https://javascript.ru/forum/misc/43311-organizaciya-koda-v-publichnojj-biblioteke.html)

Antonius 02.12.2013 02:34

Цитата:

Сообщение от nerv_ (Сообщение 283904)
Прототипы + соглашения + обертка для new. С другой стороны смотря для кого пишешь - можно и не оборачивать new. Тот, кто используют приватные методы извне - сам дурак :)

Ну если бы только сам использовал — не парился бы насчет new, а если все-таки опубликую — надо будет или обертку самому добавить, или в инструкции описать. Сам добавлять почему не хочу — во-первых это лишний элемент в пространстве имен, помимо самого конструктора, а во-вторых (и это главное) не могу придумать имя, которое бы было коротким, понятным, и при этом не было похоже на типичное имя переменной, которая уже может быть в проекте. Поэтому пусть сами имя назначают :)

nerv_ 02.12.2013 02:35

Цитата:

Сообщение от Antonius
во-первых это лишний элемент в пространстве имен, помимо самого конструктора, а во-вторых (и это главное) не могу придумать имя, которое бы было коротким, понятным, и при этом не было похоже на типичное имя переменной

var obj = Constructor.create(params);

Constructor.create = function(params) {
    return new Constructor(params);
};

kobezzza 02.12.2013 02:36

Цитата:

Сообщение от nerv_ (Сообщение 283904)
Тот, кто используют приватные методы извне - сам дурак :)

золотые слова:)

К слову, если очень нужно запретить изменение метода, то можно использовать "заморозку" (seal, freeze, preventExtensions), но не понимаю зачем, ибо если челочек осмысленно юзает приватные методы извне, то он априори не прав.

Antonius 02.12.2013 02:50

Насчет того, как принято в JS, кажется начинаю понимать :)
В принципе некоторый опыт с другими языками (в том числе ООП) был, но давно. И по сравнению с ними в JS все как-то непривычно, кажется, надо просто понять, что «тут это нормально».

Кстати, где можно почитать насчет seal, freeze, preventExtensions и т. д. Использовать здесь точно не буду, просто чтобы быть в курсе...


nerv_, это понятно, сам о таком думал, но особенности задачи таковы, что такая запись будет слишком громоздкой, предполагаю, что в коде чаще будет много коротких цепочек вызовов, и там такая длинная инициализация будет перегружать исходник и ухудшать читаемость.

Если бы объекты создавались редко, а затем интенсивно модифицировались — можно было бы и так, но пока мне кажется, что именно для этой задачи — не очень красивый вариант.

nerv_ 02.12.2013 11:56

Цитата:

Сообщение от Antonius
Кстати, где можно почитать насчет seal, freeze, preventExtensions и т. д. Использовать здесь точно не буду, просто чтобы быть в курсе...

http://learn.javascript.ru/descriptors-getters-setters

Цитата:

Сообщение от Antonius
Если бы объекты создавались редко, а затем интенсивно модифицировались — можно было бы и так, но пока мне кажется, что именно для этой задачи — не очень красивый вариант.

можешь использовать "Шаблоны принудительного использования new":
1.
'use strict';

function Waffle() {
    alert(this === undefined);
    this.tastes = 'yummy';
}

new Waffle();
Waffle();

В строгом режиме ES5 ссылка this больше не указывает на глобальный объ-
ект.
2.Возвращать из конструктора "другой" объект:
function Waffle() {
    var obj = Object.create(Waffle.prototype);
    obj.tastes = 'yummy';
    alert(obj instanceof Waffle);
    return obj; 
}
new Waffle();
Waffle();

3.Использовать конструктор вызывающий сам себя:
function Waffle() {
    if (!(this instanceof Waffle)) {
        return new Waffle();
    }
    this.tastes = 'yummy';
    alert(this instanceof Waffle);
}
new Waffle();
Waffle();


*писал на скорую руку, мог ошибиться...

Maxmaxmaximus3 02.12.2013 13:22

Цитата:

Сообщение от nerv_
В строгом режиме ES5 ссылка this больше не указывает на глобальный объ-
ект.

в смысле при вызове любой функции всегда создается Object.create(func.prototype) ????

kobezzza 02.12.2013 14:49

Цитата:

Сообщение от Maxmaxmaximus3 (Сообщение 283966)
в смысле при вызове любой функции всегда создается Object.create(func.prototype) ????

Если у функции не указан объект вызова, то он равен undefined (вместо window как раньше было)

Antonius 02.12.2013 17:08

nerv_, спасибо :) Первый способ не подходит, поскольку требует обязательного использования "use strict", но на будущее буду иметь в виду. Остальные — интересно.

Все-таки учиться только самостоятельно по источникам в учебниках, литературе не так эффективно, вот даже по простым вопросам общение с более опытными разработчиками сразу приносит ощутимую пользу.

Antonius 09.12.2013 06:53

Пожалуй, придется поднять тему снова :(

Возник такой вопрос (опять же из разряда «как принято поступать в таких случаях»). Опять же не знаю, пригодится оно мне в итоге или нет, но разобраться в любом случае хочется.

В корневом объекте, который объявлен в скрипте, есть поля, в свою очередь хранящие структурированную информацию. Например, координаты
{ x: 1, y: 2}
. Сейчас, чтобы проверить, что там действительно находятся координаты, иногда приходится использовать проверки типа
if (this.coord && typeof this.coord.x == 'number' && typeof this.coord.y == 'number') {…}

Например, если данные получены извне и еще не провалидированы.

Есть мысль объявить для таких объектов конструкторы и проверять
if (this.coord instanceof Coord) {…}

Валидировать можно при инициализации объекта, например.

Опять возникает проблема засорения пространства имен. Библиотека уже объявляет корневой объект (например, LibraryRoot, сам является конструктором), и не хочется помимо него вводить отдельные конструкторы.

Пока приходит в голову только объявлять конструкторы как LibraryRoot.Coord, но что-то меня смущает в этом варианте. Собственно, вопрос, нормально ли это или есть способы получше?

kobezzza 09.12.2013 08:16

LibraryRoot.Coord. Нормально, много так где сделано.


Часовой пояс GMT +3, время: 21:07.