от Java до JavaScript: объектная модель - PullRequest
8 голосов
/ 23 августа 2011

Я пытаюсь портировать приложение, которое я написал в java, на javascript (фактически используя coffeescript).

Теперь я чувствую себя потерянным ... что вы предлагаете сделать для создания свойств класса? Должен ли я использовать геттер / сеттеры? Я не люблю это делать:

myObj.prop = "hello"

потому что я мог бы использовать несуществующие свойства, и было бы легко что-то неправильно набрать ..

Как я могу сделать javascript немного похожим на java с закрытыми, публичными конечными свойствами и т. Д.? Любое предложение?

Ответы [ 8 ]

8 голосов
/ 23 августа 2011

Если вы просто переведите свой Java-код в JavaScript, вы будете постоянно бороться с объектной моделью JavaScript, которая основана на прототипах, а не на классах.У объектов нет личных свойств, нет конечных свойств, если только вы не используете ES5-совместимый движок (вы не упомянули, какова ваша целевая среда выполнения; браузеры не используют ES5-совместимую,еще пару лет) вообще никаких классов .

Вместо этого я рекомендую вам подробно рассказать о том, как на самом деле работает ориентация объектов в JavaScript, а затем собрать свое приложениеполностью осознавая, как это делает JavaScript.Это нетривиально, но полезно.

Некоторые статьи, которые могут быть полезны.Я начинаю с замыканий, потому что для понимания JavaScript абсолютно необходимо понимание замыканий, а большинство решений для «закрытых членов» полагаются на замыкания.Затем я ссылаюсь на пару статей Дугласа Крокфорда.Крокфорд требуется читать, если вы собираетесь работать на JavaScript, даже если вы в конечном итоге не согласны с некоторыми из его выводов.Затем я указываю на пару статей, конкретно посвященных классическим вещам.

Обращаясь к некоторым вашим конкретным вопросам:

чтовы предлагаете сделать, чтобы создать свойства класса?Должен ли я использовать геттер / сеттеры?Мне не нравится делать это:

myObj.prop = "hello"

, потому что я мог бы использовать несуществующие свойства, и было бы легко что-то неправильно набрать ..

Нет, я предпочитаю использовать TDD , чтобы убедиться, что, если у меня есть опечатка, она обнаружится в тестировании.(Хороший редактор, завершающий код, также будет полезен здесь, хотя действительно хорошие редакторы, завершающие код JavaScript, невелики.) Но вы правы, что методы получения и установки в смысле Java (такие методы, какgetFoo и setFoo) сделает более очевидным, когда вы создаете / получаете доступ к свойству, которое вы не определили заранее (например, через опечатку), вызывая ошибку времени выполнения, вызываяфункция, которая не существует.(Я говорю «в смысле Java», потому что JavaScript с ES5 имеет различного рода «getters» и «setters» , которые прозрачны и не помогут с этим.) Так что это аргумент для использованияих.Если вы это сделаете, вы можете использовать компилятор Google Closure для сборок релизов, так как он будет встроен в них.

Как я могу сделать javascript немного похожим на java,с личным ...

Я связал статью Крокфорда о частных членах и мою собственную, в которой перечислены другие способы.Самое базовое объяснение модели Крокфорда таково: вы используете переменную в контексте, созданном с помощью вызова вашей функции конструктора, и функцию, созданную в этом контексте (замыкание), которая имеет к ней доступ, а не свойство объекта:

function Foo() {
    var bar;

    function Foo_setBar(b) {
        bar = b;
    }
    function Foo_getBar() {
        return bar;
    }

    this.setBar = Foo_setBar;
    this.getBar = Foo_getBar;
}

bar не является свойством объекта, но функции, определенные в контексте с ним, имеют постоянную ссылку на него. Это прекрасно, если у вас будет небольшое количество Foo объектов. Если у вас будут тысячи Foo объектов, которые вы, возможно, захотите пересмотреть, потому что каждый Foo объект имеет свои две функции (действительно разные Function экземпляра) для Foo_getBar и Foo_setBar.

Вы часто будете видеть выше написанное так:

function Foo() {
    var bar;

    this.setBar = function(b) {
        bar = b;
    };
    this.getBar = function() {
        return bar;
    };
}

Да, это короче, но теперь функции не имеют имен, а присвоение имен вашим функциям помогает вашим инструментам .

Как я могу сделать javascript немного похожим на java, с ... public final properties

Вы можете определить получатель в стиле Java без установщика. Или, если ваша целевая среда будет соответствовать ES5 (опять же, браузеры еще нет, это будет еще через пару лет), вы можете использовать новую функцию Object.defineProperty, которая позволяет вам устанавливать свойства это не может быть записано.

Но моя главная мысль - принять язык и среду, в которой вы работаете. Изучите это хорошо, и вы обнаружите, что применяются другие шаблоны, чем в Java. Оба - отличные языки (я часто их использую), но они работают по-разному и приводят к разным решениям.

3 голосов
/ 23 августа 2011

Вы можете использовать шаблон модуля , чтобы сделать частные свойства и общедоступные средства доступа еще одним вариантом.

2 голосов
/ 23 августа 2011

Это не дает прямого ответа на ваш вопрос, но я бы отказался от идеи сделать приложение JavaScript похожим на Java. Это действительно разные языки (несмотря на некоторые сходства в синтаксисе и в их названии). Как общее утверждение, имеет смысл принять идиомы целевого языка при переносе чего-либо.

1 голос
/ 26 ноября 2012

JavaScript имеет функцию, позволяющую функциям-конструкторам возвращать любой объект (не обязательно this ). Итак, ваша функция конструктора может просто вернуть прокси-объект, который разрешает доступ только к открытым методам вашего класса. Используя этот метод, вы можете создать настоящий защищенный член, как в Java (с наследованием, вызовом super () и т. Д.)

Я создал небольшую библиотеку для оптимизации этого метода: http://idya.github.com/oolib/

1 голос
/ 23 августа 2011

В настоящее время есть много вариантов для вас, вы можете проверить библиотеку dojo.В додзе вы можете кодировать в основном как Java-программирование

  1. КлассJavascript не имеет системы классов, такой как Java, dojo предоставляет dojo.declare для определения функциональности, имитирующей это.Проверьте эту страницу .Есть переменная поля, метод конструктора, расширяемый от другого класса.
0 голосов
/ 23 августа 2011

Я автор книги CoffeeScript от PragProg.Прямо сейчас я использую CoffeeScript в качестве основного языка;Я свободно говорил на JavaScript в процессе изучения CoffeeScript.Но до этого моим лучшим языком была Java.

Так что я знаю, через что вы проходите.Java имеет очень сильный набор лучших практик, которые дают вам четкое представление о том, что такое хороший код: чистая инкапсуляция, детализированные исключения, подробные JavaDocs и шаблоны проектирования GOF повсюду.Когда вы переключаетесь на JavaScript, это идет прямо в окно.Существует несколько «лучших практик» и более смутное ощущение «это элегантно».Затем, когда вы начинаете видеть ошибки, это невероятно расстраивает - нет ошибок во время компиляции и гораздо меньше, менее точных ошибок во время выполнения.Это как играть без сети.И хотя CoffeeScript добавляет некоторый синтаксический сахар, который может показаться знакомым для Java-кодеров (особенно классов), это действительно не более чем прыжок.

Вот мой совет: научитесь писать хороший код CoffeeScript / JavaScript.Попытка сделать так, чтобы Java выглядела как путь к безумию (и поверьте мне, многие пытались; см. Почти любой код JS, выпущенный Google).Хороший JS-код более минималистичен.Не используйте get / set методы;используйте исключения экономно;и не используйте классы или шаблоны проектирования для всего.В конечном счете, JS является более выразительным языком, чем Java, а CoffeeScript тем более.Как только вы привыкнете к ощущению опасности, которое вам сопутствует, оно вам понравится.

Одно замечание: скрипты JavaS, вообще говоря, ужасны, когда дело доходит до тестирования.Существует множество хороших сред тестирования JS, но надежное тестирование гораздо реже, чем в мире Java.Так что в этом отношении JavaScripters может научиться у Java-кодеров.Использование TDD также было бы отличным способом облегчить ваши опасения по поводу того, насколько легко делать ошибки, которые в противном случае не были бы обнаружены до тех пор, пока не запустится какая-то конкретная часть вашего приложения.

0 голосов
/ 23 августа 2011

Я в основном согласен с @Willie Wheeler, что вам не следует слишком стараться сделать свое приложение похожим на Java - есть способы использовать JavaScript для создания таких вещей, как частные члены и т. Д. - Дуглас Крокфорд и другиенаписано о таких вещах.

0 голосов
/ 23 августа 2011

Додзё - один из вариантов. Я лично предпочитаю Прототип . У этого также есть структура и API для создания классов и использования наследования более "java-ish" способом. См. Метод Class.create в API. Я использовал его в нескольких веб-приложениях, над которыми работал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...