【问题标题】:Any tools to check if a Javascript property exists or not?有什么工具可以检查 Javascript 属性是否存在?
【发布时间】:2023-09-04 23:53:01
【问题描述】:

给出一个示例代码:

var yyy = { abc : 1 },
    xxx = yyy.abcc + 1;

它不会抛出任何错误,但有一个错字,其中 yyy.abcc 应该是 yyy.abc,因此由于错字错误,xxx 现在等于“NaN”。

我使用 jslint、jshint 来检查代码中的问题,但它不会告诉你 abcc 是否是有效属性。

有没有像 jslint 或 jshint 这样的工具可以检查这个?

【问题讨论】:

  • "if (undefined != yyy.abc)" 不应该做这项工作吗?或“如果 (NaN != ParseInt(yyy.abc))”。
  • @Ricola3D:虽然这不是一个工具;)
  • 不确定有什么工具,但是如果你使用TypeScript,编译器肯定会抛出错误。所有 JavaScript 都与 TypeScript 兼容。因此,您只需复制并粘贴您的代码即可。
  • @Arun 谢谢!它确实能够检查问题中示例的问题,但这意味着我可能需要将我的代码转换为 TypeScript 才能享受全部功能。因为只需复制并粘贴我的 javascript 代码以使用 Typescript 进行检查,它就无法检查依赖项(例如,如果我的代码使用 jQuery,它将给出错误 TS2095:找不到符号 '$'。)
  • 用工具来测试这个真的很难,因为你总是可以修改对象原型来拥有一个名为abcc的属性。仍然可能有一些工具至少会发出警告,但我不知道。我建议进行单元测试以在您的代码中发现此类错误。

标签: javascript lint jshint


【解决方案1】:

处理这些类型的常见拼写错误和错误确实是 Javascript 生态系统中的一个巨大漏洞,我希望更多人关注它。这个问题是八年前提出的,至今仍未得到好的答案,这一事实令人担忧。

我查看了一堆 Javascript 工具,我发现唯一适合您的情况的工具是 Typescript 编译器 tsc

不幸的是,由于 Javascript 映射的动态特性,它在技术上并不能以您编写它的确切方式处理您的情况,因为映射没有可以强制执行的严格属性,即使是编译器也是如此。但是,如果您改为使用适当的 Javascript 类,它确实有效,您确实应该为其他类提供的好处做任何事情。

例如,如果我将您的代码重写为:

class MyClass {
    constructor() {
        this.abc = 1;
    }
}

var yyy = new MyClass();
var xxx = yyy.abcc + 1;

并将其放入文件 test.js,然后创建一个 Typescript 配置文件 tsconfig.json 文件,其中包含(大部分只是来自 tsc --init 的默认输出):

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "allowJs": true,
    "checkJs": true,
    "outDir": "./dist",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": [
    "test.js"
  ]
}

然后运行:

tsc --build tsconfig.json

它正确输出错误:

test.js:11:15 - error TS2551: Property 'abcc' does not exist on type 'MyClass'. Did you mean 'abc'?

11 var xxx = yyy.abcc + 1;
                 ~~~~

  test.js:6:9
    6         this.abc = 1;
              ~~~~~~~~~~~~
    'abc' is declared here.


Found 1 error.

更好的是,它提出了一个有用的解决方案,这在编译器中是很少见的。

要安装tsc 及其依赖的类型定义,您可以运行:

sudo npm install typescript -g
npm install @types/node --save-dev

【讨论】:

    【解决方案2】:

    不要把事情复杂化 :) 第一个答案是一个很好的答案,javascript 中的每个对象都有一个原型,可以通过“if (undefined != yyy.abc)”进行检查,这将告诉您“abc”是否存在,var yyy 证明 yyy 不存在本身未定义。

    【讨论】:

    • 我假设我们不会在每次出现时都检查 yyy.abc?假设 yyy.abc 在代码的不同区域被大量使用,我们检查主要区域是否 ( undefined != yyy.abc ) 但不是每次出现?如果没有,那么每个变量都会进行大量检查..
    • 嗯,我不知道你的代码来回答这个问题:),但通常如果是这种情况,那么也许你需要一些因素。但同样只有通过查看代码我才能回答这个问题:)