Как лучше всего сообщить пользователям функций моей библиотеки, что переданные переменные имеют неверный тип - PullRequest
5 голосов
/ 10 января 2009

Я сейчас нахожусь в создании библиотеки функций javascript. Главным образом для моего собственного использования, но вы никогда не можете быть уверены, что кто-то еще использует его в своих проектах, я, по крайней мере, создаю его так, как будто это могло произойти.
Большинство методов работают, только если переданные переменные имеют правильный тип данных. Теперь мой вопрос: как лучше всего предупредить пользователей о том, что переменная имеет неправильный тип? Должен ли кто-то выбросить такую ​​ошибку?

function foo(thisShouldBeAString){ //just pretend that this is a method and not a global function
 if(typeof(thisShouldBeAString) === 'string') {
  throw('foo(var), var should be of type string');
 }
 #yadayada
}

Я знаю, что javascript выполняет внутреннее преобразование типов, но это может привести к очень странным результатам (например, '234' + 5 = '2345', но '234' * 1 = 234), и это может заставить мои методы делать очень странные вещи.

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

Ответы [ 6 ]

4 голосов
/ 10 января 2009

Проблема с проверкой типов заключается в том, что ее довольно сложно сделать. Например: -

var s = new String("Hello World!");
alert(typeof s);

Что получает предупреждение? Ответ: «объект». Это правда, это глупый способ инициализации строки, но я вижу это довольно часто, тем не менее. Я предпочитаю делать попытки конвертации в случае необходимости или просто ничего не делать.

Сказав, что в среде Javascript, в которой у меня есть полный контроль (который не true, если вы просто предоставляете библиотеку), я использую этот набор настроек прототипа: -

String.prototype.isString = true;
Number.prototype.isNumber = true;
Boolean.prototype.isBoolean = true;
Date.prototype.isDate = true;
Array.prototype.isArray = true;

Следовательно, тестирование для распространенных типов может быть простым: -

if (x.isString)

хотя вам все еще нужно следить за нулем / неопределенным: -

if (x != null && x.isString)

В дополнение к тому, что нужно избегать new String("thing") гоча, этот подход особенно важен для дат и массивов.

2 голосов
/ 10 января 2009

Несколько небольших замечаний по проверке типов - на самом деле все не так сложно:

Используйте typeof для проверки примитивов и instanceof для проверки конкретных типов объектов.

Пример: проверка строк с

typeof x === 'string'

или

typeof x === 'string' || x instanceof String

если вы хотите включить строковые объекты.

Чтобы проверить массивы, просто используйте

x instanceof Array

Это должно работать достаточно хорошо (есть несколько известных исключений - например, в Firefox 3.0.5 есть ошибка, где window instanceof Object === false хотя window.__proto__ instanceof Object === true).

edit: Есть еще некоторые проблемы с обнаружением функциональных объектов:

В принципе, вы можете использовать typeof func === 'function' и func instanceof Function.

Проблема в том, что в неназванном браузере большой корпорации эти проверки возвращают неверные результаты для некоторых предопределенных функций (их тип задается как 'object'). Я не знаю обходного пути для этого - проверки работают надежно только для пользовательских функций ...

edit2: Существуют также проблемы с объектами, переданными из других окон / фреймов, поскольку они будут наследоваться от разных глобальных объектов - то есть instanceof завершится ошибкой. Обходные пути для встроенных объектов существуют: например, вы можете проверить наличие массивов с помощью Object.prototype.toString.call(x) === '[object Array]'.

1 голос
/ 10 января 2009

Как насчет throw: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/throw

Также тип не очень хорошо различает Array, Null, Object. Посмотрите на функцию здесь: http://javascript.crockford.com/remedial.html, плюс есть несколько других способов сделать это.

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

1 голос
/ 10 января 2009

Такие библиотеки, как jQuery, не сообщают пользователю об ошибке.

Если функция ожидает число, а пользователь передает строку, функция просто возвращается, ничего не делая.

Таким образом, вы избежите появления ошибок JavaScript на реальном веб-сайте.

PS. Просто всегда проверяйте вводимые параметры, чтобы избежать появления ошибок JavaScript.

0 голосов
/ 10 января 2009

Вы можете проверить наличие некоторого значения, такого как «debug = 1». Если есть - вы можете вывести ошибки, такие как оповещения. Так что в режиме разработки пользователь увидит их, а на реальном сайте отключит. Точно так же браузер не покажет вам сообщение об ошибке - вам нужно посмотреть на консоль JS.

Также есть FireBug. Вы можете обнаружить это и также поместить сообщения отладки FB.

0 голосов
/ 10 января 2009

Как насчет простого преобразования строки в числовой тип данных при запуске функции?

Вы всегда можете определить тип данных 'string'. Ты не можешь?

...