如何处理JavaScript中对象构造函数的无效输入
我正试图了解Javascript中的OOP(我也从未在任何其他语言中真正使用过OOP,所以这是我第一次使用它)。我编写了一个类,该类需要构造函数的输入,但构造函数只能处理特定格式的字符串如何处理JavaScript中对象构造函数的无效输入,javascript,oop,class,exception,throw,Javascript,Oop,Class,Exception,Throw,我正试图了解Javascript中的OOP(我也从未在任何其他语言中真正使用过OOP,所以这是我第一次使用它)。我编写了一个类,该类需要构造函数的输入,但构造函数只能处理特定格式的字符串 我有一个正则表达式可以用来检查输入,但是如果它不匹配(或者根本没有输入),我不知道该怎么做。我应该抛出某种异常吗?如果是这样,我该怎么做?如果要抛出异常,可以这样做: throw new Error("Illegal construction string."); (Error对象不是必需的,也就是说,您可以
我有一个正则表达式可以用来检查输入,但是如果它不匹配(或者根本没有输入),我不知道该怎么做。我应该抛出某种异常吗?如果是这样,我该怎么做?如果要抛出异常,可以这样做:
throw new Error("Illegal construction string.");
(Error
对象不是必需的,也就是说,您可以抛出一个普通字符串,但是如果您处理onerror
事件,它会使错误消息很好地显示出来。)
在使用用户输入时,您可能需要在调用构造函数之前验证字符串,并向用户提供比异常结果更友好的消息。当然,您仍然可以在构造函数中进行验证,以确保没有任何东西从中溜走。通常有两种方法可以实现这一点:要么抛出异常,要么返回一些指示失败的值(如
未定义的)。在JavaScript中,我更倾向于后者,更宽容的方法
我还发现第二种方法更接近于模仿许多JavaScript本身。例如,在Python中,如果试图访问对象上不存在的属性,它将抛出异常
>>> foo = 0
>>> foo.idontexist
AttributeError: 'int' object has no attribute 'idontexist'
> var foo = new Date('thisisnotadate');
> foo
Invalid Date
而在JavaScript中,它只返回未定义的
> var foo = 0;
> foo.idontexist
undefined
许多函数和对象也是这样工作的。例如,Date
在传递不正确的日期字符串时返回一个无效日期
对象,而不是引发异常
>>> foo = 0
>>> foo.idontexist
AttributeError: 'int' object has no attribute 'idontexist'
> var foo = new Date('thisisnotadate');
> foo
Invalid Date
JavaScript构造函数(用调用的函数)总是需要返回一个对象,在正常调用时不能返回false
、null
或类似的值。因此,您有两种选择:
- 从中抛出一个异常。您可以使用一个脚本中的每个javascript值来执行此操作。然后,在建筑外用一根绳子抓住他们
- 返回一个普通对象,但内部值设置为无效的指针。
Date
构造函数就是这样做的,例如,获取属性就会得到NaN
s
此外(特别是在使用异常时),您可能会在构造函数上提供一个额外的验证函数(返回布尔值)作为静态属性,因此您甚至可以在构建对象之前使用它。例如:
function Decryption(str) {
if (! Decryption.test(str))
throw new SyntaxError("invalid encryption");
this.result = decrypt(str);
}
Decryption.test = function(str) {
return /MyCoolRegExp/.test(str);
};
在JavaScript中,抛出异常不是您想要做的事情。例外情况只会在例外情况下发生(duh…)。这与Java不同,Java到处使用异常进行通信。造成这种差异的原因是JS中异常处理的速度非常慢
因此,您可以很好地为构造函数配备一个抛出
,但这不应该在生产中出现。您最好先检查构造函数之外的有效性
做:
不要:
try {
foo = new MyObject(input);
} catch (ex) {
// show message to the user
}
谁应该构造这些对象,字符串从哪里来?@Bergi字符串来自用户在网页框中键入的内容。哪些功能可以从字符串构建对象?对象在构造时做什么?对象是用加密字符串构造的,然后尝试解密它并保存有关它的其他细节(长度、密钥等)。你是说在OOP中,当构造函数输入丢失或无效时抛出错误是正常的做法吗?@Grezzo:是,如果构造函数不能正确初始化对象,异常是阻止对象完成的唯一表现良好的方法。我喜欢返回无效对象的想法。是否可以使用自定义类执行此操作。例如,我的类叫做person,我可以返回一个无效的person对象吗?老实说,我不喜欢无效对象的概念。想一想:你打算拿这样的东西做什么?我想,Invalid Date
是JS早期遗留下来的东西,在JS早期,某些奇怪的概念是从Java复制的。还要注意,您不能从构造函数返回未定义的。return
语句将被忽略。老实说,我不喜欢直接使用new
构造。我通常选择类似工厂的函数,通过细粒度控制动态创建对象。我完全赞成在调用构造函数之前进行验证,但我不应该也在构造函数中进行检查吗?否则它将不会非常健壮。是的,您可以同时使用这两种方法。这取决于您是否计划重新使用/发布对象。如果你只在一个网站上使用它,我就不用担心重复检查了。为网站编写脚本总是在代码大小、速度和可维护性之间进行权衡。我想明确一点:在我看来,throw
无疑对调试有用,但应该尽可能避免。哦,我喜欢这种验证功能。我可以把它作为我的对象的一个方法,还是因为对象还不存在而不起作用?test
函数不是解密
实例的方法,而是构造函数[object]的一个属性。我不确定我是否遵循了它。我想我还需要进一步了解方法和属性之间的区别。我认为方法只是一个对象属性,碰巧是一个函数……是的,没错。只不过,一个方法对它所调用的对象做了一些事情,test
函数在“class”对象上“只是名称空间”。我刚刚在上面的示例中添加的getLength()
“方法”(由所有解密
对象继承的原型)使用实例的result
属性