读取未定义的对象属性时强制 JavaScript 异常/错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6511542/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Force JavaScript exception/error when reading an undefined object property?
提问by stackoverflowuser2010
I'm an experienced C++/Java programmer working in Javascript for the first time. I'm using Chrome as the browser.
我是一位经验丰富的 C++/Java 程序员,第一次使用 Javascript。我使用 Chrome 作为浏览器。
I've created several Javascript classes with fields and methods. When I read an object's field that doesn't exist (due to a typo on my part), the Javascript runtime doesn't throw an error or exception. Apparently such read fields are 'undefined'. For example:
我已经创建了几个带有字段和方法的 Javascript 类。当我读取不存在的对象字段时(由于我的拼写错误),Javascript 运行时不会抛出错误或异常。显然,这样的读取字段是“未定义的”。例如:
var foo = new Foo();
foo.bar = 1;
var baz = foo.Bar; // baz is now undefined
I know that I can check for equality against 'undefined' as mentioned in "Detecting an undefined object property in JavaScript", but that seems tedious since I read from object fields often in my code.
我知道我可以检查与“未定义”的相等性,如“在 JavaScript 中检测未定义的对象属性”中所述,但这似乎很乏味,因为我经常在我的代码中从对象字段中读取。
Is there any way to force an error or exception to be thrown when I read an undefined property?
当我读取未定义的属性时,有什么方法可以强制抛出错误或异常?
And why is an exception thrown when I read an undefined variable (as opposed to undefined object property)?
为什么当我读取一个未定义的变量(而不是未定义的对象属性)时会抛出异常?
采纳答案by nrabinowitz
This looks to me like a classic case of trying to shoehorn one language into the paradigms of another - better IMHO to change your coding style to follow how Javascript does things than try to make it conform to C++ concepts and expectations.
在我看来,这像是试图将一种语言硬塞进另一种语言的范式的经典案例 - 恕我直言,更好地改变您的编码风格以遵循 Javascript 的工作方式,而不是试图使其符合 C++ 的概念和期望。
That said, if you want to throw an error as you suggest, you'll need to define some sort of custom getProperty
function, either on the object you're trying to access or in the global scope. An implementation might look like this:
也就是说,如果您想按照您的建议抛出错误,您需要定义某种自定义getProperty
函数,无论是在您尝试访问的对象上还是在全局范围内。一个实现可能如下所示:
function getProperty(o, prop) {
if (o.hasOwnProperty(prop)) return o[prop];
else throw new ReferenceError('The property ' + prop +
' is not defined on this object');
}
var o = {
foo: 1,
bar: false,
baz: undefined
};
getProperty(o, 'foo'); // 1
getProperty(o, 'bar'); // false
getProperty(o, 'baz'); // undefined
getProperty(o, 'foobar');
// ReferenceError: The property baz is not defined on this object
But this is ugly, and now you've got this custom language construct in all of your code, making it less portable (if, for example, you wanted to copy any part of your code into another script, you'd have to copy your new function too) and less legible to other programmers. So I'd really recommend working within the Javascript paradigm and checking for undefined
before accessing the properties you need (or setting up your code so that false-y values are expected and don't break things).
但这很丑陋,现在您在所有代码中都有这种自定义语言结构,这使得它的可移植性降低(例如,如果您想将代码的任何部分复制到另一个脚本中,则必须复制您的新函数也是如此),其他程序员不太容易辨认。所以我真的建议在 Javascript 范式中工作并undefined
在访问您需要的属性之前检查(或设置您的代码以便预期 false-y 值并且不会破坏事物)。
As to your second question, why Javascript throws an error for undefined variables but not for undefined object properties, I can't give any better answer than "Because that's what's in the language specification." Objects return undefined
for undefined property names, but undefined variable references throw an error.
至于你的第二个问题,为什么 Javascript 为未定义的变量抛出错误而不是为未定义的对象属性抛出错误,我不能给出比“因为这就是语言规范中的内容”更好的答案。对象返回undefined
未定义的属性名称,但未定义的变量引用会引发错误。
回答by P. Meller
This can be achieved using ES6 proxies:
这可以使用ES6 代理来实现:
function disallowUndefinedProperties(obj) {
const handler = {
get(target, property) {
if (property in target) {
return target[property];
}
throw new Error(`Property '${property}' is not defined`);
}
};
return new Proxy(obj, handler);
}
// example
const obj = { key: 'value' };
const noUndefObj = disallowUndefinedProperties(obj);
console.log(noUndefObj.key);
console.log(noUndefObj.undefinedProperty); // throws exception
回答by zertyuio
Is there any way to force an error or exception to be thrown when I read an undefined property?
当我读取未定义的属性时,有什么方法可以强制抛出错误或异常?
That's possible using ES6 proxies as has been said in previous responses. I have done the small node module "zealit" to avoid having to implement it every time.
正如之前的回复中所说,使用 ES6 代理是可能的。我已经完成了小节点模块“zealit”以避免每次都实现它。
If someone is interested : https://www.npmjs.com/package/zealit
如果有人感兴趣:https: //www.npmjs.com/package/zealit
const zealit = require('zealit')
const ref = { foo: true, bar: undefined }
ref.foo // true
ref.bar // undefined
ref.baz // undefined
const zealed = zealit(ref)
zealed.foo // true
zealed.bar // undefined
zealed.baz // throws a ReferenceError
回答by adw
Firefox has an option javascript.options.strict
(in about:config
). If you enable this, warnings will be logged to the console for many common mistakes, including reading an undefined property, using =
instead of ==
in an if
, etc.
Firefox 有一个选项javascript.options.strict
(在 中about:config
)。如果启用此功能,许多常见错误的警告将记录到控制台,包括读取未定义的属性、使用=
而不是==
inif
等。
(Of course, that's not to say such code is necessarily wrong.)
(当然,这并不是说这样的代码一定是错误的。)
回答by g.d.d.c
Is there any way to force an error or exception to be thrown when I read an undefined property?
当我读取未定义的属性时,有什么方法可以强制抛出错误或异常?
In short, no. You can always test for whether or not you ended up with undefined by either comparing to undefined
, like you said, or by attempting to access a second level attribute:
简而言之,没有。您始终可以通过比较 to undefined
,如您所说,或尝试访问二级属性来测试您是否以 undefined 结束:
s = Foo()
s.bar = 1
s['Bar'] // returns undefined.
s['Bar']['Baz'] // Throws TypeError, s.Bar is undefined.
Additionally, undefined
fails in a conditional check, so you can get away with this as a shorthand for the comparison:
此外,undefined
条件检查失败,因此您可以将其作为比较的速记:
if (s['Bar']) {
// Something here only if s['Bar'] is set.
}
Be aware that this short hand could cause unexpected behavior if s['Bar'] was set, but was a 'Falsey' value, and you were only concerned with whether or not it came back undefined.
请注意,如果 s['Bar'] 已设置,但它是一个 'Falsey' 值,则此简写可能会导致意外行为,并且您只关心它是否返回未定义。
回答by Razzle
There is great power in consistency (like in the STL from Alexander Stepanov that Stroustrup adopted into C++). One simple reason for the inconsistent treatment of undeclared properties vs undeclared variables is probably a reflection of the thought and effort that went into evolving the different languages and another is probably the abilities of the people involved.
一致性有很大的力量(就像 Stroustrup 在 C++ 中采用的来自 Alexander Stepanov 的 STL 一样)。对未声明属性与未声明变量的不一致处理的一个简单原因可能是进化不同语言的思想和努力的反映,另一个可能是相关人员的能力。
It also impacts the kind of applications you would entrust to any given language. You hopefully wouldn't try to write mission critical software that runs a multimillion dollar cruise liner engine management system in javascript, for example.
它还会影响您委托给任何给定语言的应用程序类型。例如,您希望不会尝试编写运行价值数百万美元的游轮引擎管理系统的 javascript 任务关键软件。
(Probably not a popular answer for javascript aficionados.)
(对于 javascript 爱好者来说,可能不是一个受欢迎的答案。)