Я знаю, что javascript использует типизацию утиной утилитой, и сначала я подумал, что это облегчит полиморфизм по сравнению со строго типизированными языками, такими как C #. Но теперь мои функции, которые принимают аргументы, изобилуют такими вещами, как:
if(myObj.hasSomeProperty())
или же
if(myObj.hasSomeMethod())
или же
if(isNumber(myParam))
и т.п.
Это действительно безобразно для меня. Я пришел из C # фона и считаю, что определенные интерфейсы намного лучше.
Мне интересно, если я неправильно пытаюсь применить стратегии, которые эффективны в статически типизированных языках, и есть ли лучший способ сделать это в JavaScript?
Я знаю, что просто не могу проверить, но отслеживание ошибок времени выполнения JavaScript может быть кошмаром, поскольку они не всегда происходят там, где ошибка действительно возникает в коде.
Ответы:
Просто: не всегда проверяйте свойства и методы.
В Ruby то, что вы называете, называется "типизацией курицы". На языке динамического типа «утка» вы просто верите, что вызывающая сторона передает вам подходящий объект. Работа вызывающего абонента состоит в том, чтобы соблюдать его часть контракта.
Вы путаете несколько ортогональных осей печатания здесь. Различают четыре ортогональные оси набора текста:
Поскольку вы упомянули C #: он в основном статически типизирован, но поддерживает динамическую типизацию через тип
dynamic
, он в основном номинально типизирован, но анонимные типы используют структурную типизацию, и синтаксические паттерны (такие как синтаксис понимания запросов LINQ) можно считать либо уткой типизированный или структурно типизированный, он в основном явным образом типизирован, но поддерживает неявную типизацию для аргументов универсального типа и локальных переменных (хотя регистр локальной переменной довольно странный по сравнению с большинством других языков, потому что вы не можете просто пропустить тип, вместо этого вы должны дать ему явный псевдотипvar
другими словами, если вы хотите неявный тип, вы должны явно сказать это). Независимо от того, является ли C # строго или слабо типизированным, зависит от того, какое определение двух терминов вы используете, однако обратите внимание, что в C # может быть много ошибок типов времени выполнения, особенно из-за небезопасной ковариации массива.Отладка не является простым навыком для изучения. Однако существуют методы, облегчающие отладку, например, Saff Squeeze - это метод, описанный Кентом Беком, который использует тесты и рефакторинг для отладки:
источник
IComparer<T>.Compare(T, T)
ясно только из документации, а не типа. И где в типеjava.util.Collections.binarySearch(java.util.List<T>)
сказано, что ...Действительно, типичная практика - не проверять. И, да, это означает, что вы получите ошибки javascript, о которых сообщается в другом месте, из реальной проблемы. Но на практике я не считаю это большой проблемой.
Работая в javascript, я постоянно проверяю, что я пишу. В большинстве кода у меня есть модульные тесты, которые запускаются автоматически каждый раз, когда я сохраняю свой редактор. Когда что-то неожиданно идет не так, я знаю почти сразу. У меня есть очень маленькая область кода, в которой я, возможно, допустил ошибку, так как почти всегда последнее, к чему я прикасался, имеет ошибку.
Когда я получаю ошибку во время выполнения, я, по крайней мере, получаю трассировку стека, а в случае ошибки в браузере у меня есть возможность перейти на любой уровень трассировки стека и проверить переменные. Как правило, легко отследить, откуда взялась плохая ценность, и таким образом отследить ее до исходной проблемы.
Если вы похожи на меня, когда я писал в основном на статически типизированных языках, перед тестированием я писал большие блоки кода, и у меня не было практики отследить, откуда оно взято. Программирование на языке, таком как javascript, отличается, вы должны использовать разные навыки. Я подозреваю, что подобное программирование кажется намного сложнее, потому что это не те навыки, которые вы развили, работая на других языках, таких как C #.
Сказав это, я думаю, что многое можно сказать о явных типах. Они отлично подходят для документирования и раннего обнаружения ошибок. Я думаю, что в будущем мы увидим все большее распространение таких вещей, как Flow и Typescript, которые добавят статическую проверку типов в javascript.
источник
Я думаю, что вы поступаете правильно, вам просто нужно найти стиль, который будет более приятным для вашего глаза. Вот несколько идей:
Вместо того, чтобы
if(myObj.hasSomeProperty())
вы могли использоватьif( myobj.prop !== undefined )
. Это, кстати, будет работать только в нестрогом режиме, в строгом режиме, который вам придется использоватьif( typeof myobj.prop !== 'undefined' )
.Вы можете разгрузить некоторые проверки типов в отдельные валидаторы. Преимущество этого заключается в возможности пропустить проверку после того, как интерфейсы станут зрелыми, например
if( is_valid( myobject ))
, гдеis_valid
начинается сif( !DEBUG ) return true;
.Иногда имеет смысл клонировать входные данные в каноническую форму, и в этом случае вы можете собрать различные объекты проверки в функцию / объект клонирования. Для exmaple, в
my_data = Data( myobj, otherstuff )
кData
конструктору может удобно работать все различные валидации в центральном месте.Вы можете использовать некоторую библиотеку, которая (при снижении производительности) упростит проверку вашего типа во что-то более элегантное. Даже если вы не пойдете этим путем в долгосрочной перспективе, вам может быть удобно, чтобы вы плавно перешли в свой собственный стиль. Некоторые примеры включают xtype.js , тип-чек , validator.js и т.д.
источник