如何更好地告诉使用我的库函数的用户,传递的变量类型不正确。

5

我目前在创建一个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),这可能会使我的方法执行非常奇怪的事情。
编辑: 为了让事情更加清晰:我不希望进行类型转换,传递的变量应该是正确的类型。最好的方式是告诉我的库的用户传递的变量不是正确的类型?

顺便提一下,typeof是一个操作符,而不是函数,因此不应该有括号(尽管这样做也可以)。如果(typeof thisShouldBeAString === 'string') { - I.devries
你不应该使用 throw 'a string',而是应该使用 throw new Error('a string') 来获取有用的调试信息... - Christoph
6个回答

4

类型检查的问题在于实际上相当难以实现。例如:

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

被警报的是什么?答案:对象。虽然这是一个愚蠢的初始化字符串的方式,但我还是经常看到它的使用。如果需要,我更喜欢尝试转换,否则就什么都不做。

话虽如此,在JavaScript环境中,如果我有完全控制权(如果你只是提供库,则是真的),我会使用这组原型调整:

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

因此,测试常见类型可以非常简单,例如:-
if (x.isString)

尽管如此,您仍需要注意 null/undefined:-
if (x != null && x.isString)

除了避免使用new String("thing")这个陷阱外,这种方法在处理日期和数组时特别有用。


虽然这并非必要,有时甚至不可取,但我认为这样做更加简洁高效。 - AnthonyWJones

2

关于类型检查的一些小注解 - 其实并不那么复杂:

使用 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)。

编辑:检测函数对象还有一些问题:

原则上,您可以同时使用typeof func === 'function'func instanceof Function

问题在于,在来自大公司的未命名浏览器中,这些检查对于某些预定义函数返回错误的结果(它们的类型被给定为'object')。我不知道任何解决方法 - 这些检查只对用户定义的函数可靠地起作用...

编辑2:从其他窗口/帧传递的对象也存在问题,因为它们将继承不同的全局对象 - 即instanceof会失败。内置对象的解决方法存在:例如,您可以通过Object.prototype.toString.call(x) === '[object Array]'检查数组。


1

像jQuery这样的库不会向用户报告错误。

如果一个函数期望一个数字,而用户传递了一个字符串,那么该函数只是返回而不做任何事情。

这样,您就可以避免在实时网站上弹出JavaScript错误。

PS. 确保始终对输入的参数进行类型检查,以避免抛出JavaScript错误。


但这样做也不会通知其他开发人员出现了什么问题,而且具体出了什么问题也不清楚。 - Pim Jager
如果您为您的库编写了良好的文档,开发人员将会知道,如果一个函数期望参数是数字,而开发人员传递了一个字符串,那么该函数将因此无法正常工作。 - Andreas Grech
实际上,当我收到一个错误告诉我某个库的深处出了问题时,我觉得这很不方便。 - Rene Saarsoo
基本上:进行类型检查,如果变量类型不正确,则返回false? - Pim Jager

1

关于throw,你怎么看: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/throw

此外,类型检查在数组,空值和对象之间没有很好的区分。请参考这里的函数:http://javascript.crockford.com/remedial.html,还有其他几种方法可以实现。

个人认为不应该做类型检查,因为这只会增加代码的处理时间。如果你关心性能,你就会尽可能地削减处理时间的毫秒数。好的文档将消除对检查的需求。


0

在函数启动时,将字符串静默转换为数字数据类型怎么样?

你总是可以确定“字符串”的数据类型,不是吗?


我在类型转换的主题上更清楚地表达了我的问题。 - Pim Jager

0
你可以检查是否设置了像“debug=1”之类的某些值。如果有,你可以输出警告错误。因此,在开发模式下,用户将看到它们,但在真实网站上,他会关闭它们。同样,浏览器也不会显示错误消息-您需要查看JS控制台。
还有FireBug。你可以检测它并放置FB调试信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接