如何使用严格模式而不在 JSlint 中出错

How to use strict mode and not get an error in JSlint

查看 JSlint 上的所有信息(例如 here or here),讨论是这样的

Always use strict mode since it catches many more errors. All you have to do is put 'use strict' at the top of your code. That's it! Couldn't be easier... Except when JSlint complains and tells you to put it in function scope, then you have to put all of your code inside a giant function.

我用 javascript 编写了数百个函数,并且至少 <body> 在加载时调用了一个回调函数,所以我正在努力思考我应该如何将我所有的在另一个函数中运行,但仍然确保 <body> 元素仍然可以 刺穿 外部函数并使用内部范围调用我的函数。

谁能告诉我如何为这样的东西实现严格模式

function foo(){
    "use strict"; /* Approach 1: Putting inside every function */
                  /* Extremely tedious and ugly */
    $('#example').text('Hello '+ bar());
}

function bar(){
    "use strict"; /* Approach 1: Putting inside every function */
                  /* Extremely tedious and ugly */
    return 'Beautiful';
}

function fooBar (){
    "use strict"; /* Approach 2: Putting once at the top of an outer function */
    
    /* But now how does <body> call this function? */
    function foo(){
        "use strict";
        $('#example').text('Hello '+ bar());
    }

    function bar(){
        "use strict";
        return 'Beautiful';
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body onload="foo();">
<p id='example'>
</p>
</body>

在现代 JavaScript 中,应尽可能避免内联处理程序,因为它们需要全局污染,需要使用一些参数转义丑陋的引号,并且具有荒谬的作用域链规则。因此,尝试删除内联处理程序并将你的 JavaScript 放入一个 IIFE,它可以变得严格:

(() => {
  "use strict";

  function foo() {
    $('#example').text('Hello ' + bar());
  }

  function bar() {
    return 'Beautiful';
  }
  window.addEventListener('DOMContentLoaded', foo);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
  <p id='example'>
  </p>
</body>

如果您有任何其他类似于 <body onload="foo();"> 的内联处理程序,我强烈建议重构它们。

虽然 CertainPerformance 的回答是 IMO 最好的回答,但我仍然想在我 的意思 的上下文中回答我自己的问题,也许不是我的措辞。

一些编程语言似乎不太关心作用域(我在看着你 Python),但大多数成熟的语言,C++ 是最强大的,提供某种形式的作用域 Python =22=]

/* Begin Pseudocode */
include <a>;             /* Include some external library */
external var external_a; /* Indicate that it is defined externally */
var global_a;            /* Create global scope variable */

function xyz (p_1, p_2); /* Declare global scope function */

function xyz (p_1, p_2){ /* Define function */
    return p_1 * external_a + p_2 * global_a; /* Example calculation */
}

Javascript 并没有真正导出,所以你必须将所有这些放在一个函数中,return 一个 class 和 hack[= 中的对象45=] 那种私密感 vs public, 有点像这样

(() =>{
    var global_a; /* Global function scope */
    let xyz;      /* Declare function */

    xyz = function  (p_1, p_2){ /* Define function */
        return p_1 * p_2; /* Example calculation */
    };

    return { /* Finally, we have to manually return the function */
             /* designating it as public in the process */
        xyz: xyz
    };
}(external_a); /* passed externally, essentially making it a global */

不得不以这种奇怪的方式重构你的代码库通常是一个糟糕的编程语言的危险信号,你实际上是在修改语法以获得你想要的功能,在这个过程中把自己变成一个准编译器,但是这种方法还有另一个问题:它会导致不良的编程习惯,例如定义了变量但从未使用过的变量。如果你通过 JSHint 运行 上面的 javascript 代码,它会抱怨 xyz is defined but never used。从技术上讲它是正确的,但这就是所有 API 的全部本质:写一次,以后使用...也许 。然后这导致了整个兔子洞探险,试图抑制一些 JSHint 错误(比如 xyz 被定义但从未使用过)而不抑制其他错误(比如 a 被定义但从未使用过)。可能有一种方法可以配置 JSHint 以识别这种特殊情况,但我的观点是,应该有一种简单的方法来实现这种结果,并且应该仅为该方法配置 JSHint。

现在 Javascript 技术上 确实 具有导出功能并且可以像这样使用,但对我来说,强大的语言应该创建一个模块 基于 文件,而不是基于该文件的大量修改版本,而且该模块应该导入而不是导出

var module_a = (() =>{
    var global_a; /* function scope */
    let xyz;      /* Declare function */

    xyz = function  (p_1, p_2){ /* Define function */
        return p_1 * p_2; /* Example calculation */
    };

    return {
        xyz: xyz
    };
}(external_a); /* passed externally */

export module_a;

我想我想说的是什么,我觉得我会从这个社区得到很多回击,是 Javascript 想成为一种具有高级功能的 OO 语言功能,但黑客攻击它做一件事揭示了一个弱点,然后必须再次被黑客攻击。 Javascript 在线社区未能解决这些缺点,导致 脱离现实 在线教程(source

[A] Module [a] is self-contained and reusable chunk of JavaScript code written in a modular way. Until ES6 JavaScript did not define any language construct for working with modules. So writing modular JavaScript involves the use of some coding convention.

现在这是最诚实的教程之一,但 编码约定 对我来说似乎有点淡化和阉割了。基本上作者所说的是没有干净的方法来做到这一点,所以不幸的是你不得不破解它。

所以,我对我最初的问题的长篇大论的回答是:你必须把你的整个代码库,它是全局范围的并且易于使用 API,并将它放在一个匿名函数中,然后然后在顶部粘贴一个 "use strict"; 以便 JSHint 工作,然后在一个巨大的对象中 return 您需要 public 可用的任何 API 端点,然后当 JSHint 抱怨时关于已声明但未使用的变量,您在此处粘贴 /* jshint line: ignore */ 注释,然后在结果不起作用(很可能已弃用)时删除该注释,因此将其切换为围绕未使用的变量部分(/* jshint unused: false */ ... /*jshint unused: true */) 然后在页面末尾导出 returned 对象并将其导入其他地方并使用它。