读取未定义的对象属性时强制JavaScript异常/错误?

sta*_*010 33 javascript

我是一名经验丰富的C++/Java程序员,第一次使用Javascript.我正在使用Chrome作为浏览器.

我用字段和方法创建了几个Javascript类.当我读取一个不存在的对象字段时(由于我的错字),Javascript运行时不会抛出错误或异常.显然这样的读取字段是"未定义的".例如:

var foo = new Foo();
foo.bar = 1;
var baz = foo.Bar; // baz is now undefined
Run Code Online (Sandbox Code Playgroud)

我知道我可以检查" 在JavaScript中检测未定义的对象属性 "中提到的"未定义"的相等,但这似乎很乏味,因为我经常在我的代码中读取对象字段.

当我读取未定义的属性时,有没有办法强制抛出错误或异常?

当我读取未定义的变量(而不是未定义的对象属性)时,为什么会抛出异常?

小智 20

这可以使用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
Run Code Online (Sandbox Code Playgroud)


nra*_*itz 14

这看起来像是一个尝试将一种语言塞进另一种语言范例的经典案例 - 更好的恕我直言,改变你的编码风格,以遵循Javascript的做法,而不是试图使其符合C++的概念和期望.

也就是说,如果你想按照你的建议抛出一个错误,你需要定义某种自定义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
Run Code Online (Sandbox Code Playgroud)

但这很丑陋,现在你在所有代码中都有这种自定义语言结构,使其不那么便携(例如,如果你想将代码的任何部分复制到另一个脚本中,你必须复制你的新功能也是如此)对其他程序员来说不太清晰.所以我真的建议你在Javascript范例内工作并undefined在访问你需要的属性之前检查(或者设置你的代码以便假设错误的值并且不会破坏它们).

关于你的第二个问题,为什么Javascript会为未定义的变量抛出错误而不是未定义的对象属性,我不能给出比"因为那是语言规范中的内容"更好的答案.对象返回undefined未定义的属性名称,但未定义的变量引用会引发错误.

  • 你完全错了.这里没有"鞋拔"的东西.C结构和C++/C#/ Java类都表现正常:如果您尝试读取不存在的字段,编译器将抛出错误.这不是上述语言的一些怪癖; 这也只是常识. (35认同)
  • @ stackoverflowuser2010 - 我的观点与此无关,但显然ECMAScript/Javascript设计师不同意你的意见.您可能会声称Javascript不遵循"常识",因为它是松散类型的. (10认同)
  • 目前,我认为最好的答案是使用 Flow 或 Typescript 来强制静态类型安全。当我编写原始答案时,这些选项实际上并不可用,但它们提供了比 OP 请求的更好的选项 - 通过正确的设置,您可以在编辑器中直接看到这些错误,而不是在运行时意外命中。 (3认同)

小智 7

当我读取未定义的属性时,有没有办法强制抛出错误或异常?

这可以使用ES6代理,如之前的回复中所述.我已经完成了小节点模块"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 
Run Code Online (Sandbox Code Playgroud)


adw*_*adw 6

Firefox有一个选项javascript.options.strict(in about:config).如果启用此,警告将被记录到控制台了很多常见的错误,包括读取未定义的属性,使用=的,而不是==if

(当然,这并不是说这样的代码必然是错误的.)