我应该为我编写的每一个 JavaScript 函数都使用 'use strict' 吗?

37

我应该在我编写的每一个JavaScript函数中都使用'use strict'吗?

在大型AngularJS项目中,使用严格模式的好习惯是什么?全局使用会破坏不支持它的第三方库,但每次都用'use strict'又太过冗余。

4个回答

28

在这个问题上,要注意一般倾向于过于简化的趋势。

首先,你的所有代码绝对应该在严格模式下运行。执行严格模式之外的代码会更改核心的现代JavaScript功能(请参见.call()和apply())或使其失真(静默错误)。(来自Crockford的更多信息,请查看这里。)

然而,这并没有解决你应该如何确保你的代码在严格模式下运行的问题。至少需要考虑两种情况:

在浏览器中,你的代码应该在被缩小后交付。如果你在每个函数体中都包含'use strict',你的缩小器不会将其删除,并且你将浪费字节重复使用它。你只需要在你的最外层函数作用域中使用它,即在你的模块定义顶部。一种方法是将你的缩小代码作为构建过程的一部分包装在一个单独的IIFE闭包中:

;(function (){ 
  'use strict'
  // All code here.
}())

我认为这是接近理想的做法,但它或多或少地要求您采用持续集成工作流(因为要观察严格模式下运行的代码,必须将其全部封装在一个闭包中)。如果您不以这种方式工作,那么您必须在没有被声明在另一个函数范围内的每个函数的顶部包含use strict指令。

在服务器上,当然要简单得多。代码不会被缩小,字节也不重要,所以您可以在每个文件的顶部包含use strict指令。

关于--use_strict的警告:在您控制如何运行脚本的情况下,您可能会被诱使使用--use_strict运行时标志。这很容易,但它意味着所有依赖项都必须符合严格模式的要求。由于您不能控制每个第三方的遵从性,因此通常不明智。


1
在(function())之前有一个分号“;”,这个分号的目的是什么? - Won Jun Bae
9
假设你的JS文件将被添加到另一个名为returnsFunc.js的文件中,该文件返回一个函数。那么你将得到一个函数值,后面跟着'(function () ...)',也就是说,你的文件被解释为returnsFunc.js返回的函数的输入,并且该函数被调用。在这种情况下,任何预期的功能都无法正常工作,调试会相当混乱。插入的分号可以消除这种可能性。 - Jeff McMahan
我认为一个压缩工具应该知道如果有最外层的'use strict',则删除重复的'use strict'。 - William Entriken

16

所有你写的代码1都应该处于严格模式。它有助于你捕获错误,不会忽略异常。

然而,不是每个function定义都需要在前面加上"use strict";,你只需要将其放在模块范围内 - 每个文件只需一次 - 这样它就会被所有函数继承。当你要切换到ES6模块时,它会被隐式地应用

1: 我甚至认为应该全球启用它,因为严格模式不应该破坏任何正确编写的代码。
如果它确实破坏了第三方脚本,则解决方案可能不是再次禁用严格模式...


@DouglasDaseeco 我认为我帖子的第二段回答了这个问题。第一段只是陈述一个事实。也许“是的”有误导性,我应该把它编辑掉吗? - Bergi
@DouglasDaseeco 已编辑。并且删除了那个链接。不知道为什么我在2015年觉得它有用。 - Bergi

8

简短回答是,需要!你不需要在每个函数中都包含它,只需要在每个JavaScript文件中添加一次即可。当你开始编写文件时,可以用如下的闭包(closure):

(function () {
  "use strict";
  // Rest of your code.

})();

5
为什么要加上自执行函数包裹呢?你完全可以直接把它放在文件顶部。 - bjb568
1
@bjb568 这将适用于所有函数,对吗? - Praveen Kumar Purushothaman
2
是的,还有外部作用域。 - bjb568

4
不需要冗余。使用声明即可。
"use strict";

在使用第三方库时,最好在文件或流范围内进行决策,这有助于决定是直接使用它们、包装它们还是放弃使用它们。
文件级别的自执行函数
现在越来越常见地看到整个文件或流被包含在自执行闭包中。在这种情况下,使用严格模式的声明(如上所述)插入在闭包的第一行,即...处。
(function () { 
    ...
}())

需要说明的是,自执行并非总是必要的,如果过度使用会导致加载缓慢和其他问题。

关于声明范围的更多信息

声明的范围取决于您是在函数内部还是外部放置声明,并适用于闭包作用域中声明后面的所有语句。

如果文件或流已经与更严格的模式兼容,或者可以轻松地实现兼容,则在函数内部使用该声明方式是错误的。这种冗余是不必要的,因此建议将声明放在文件顶部或流的开头。

有时只有一些函数符合更严格的规则。在这种情况下,可以使用较不理想的函数作用域,以至少鼓励在已经符合规则的函数中进行更好的编码实践。

为什么要使用严格模式?

严格模式消除了某些宽松的语言解析和执行特性,这些特性从语言设计的角度来看不太理想。这些非严格模式语言特性被认为是向后兼容的默认行为。简介和详细信息请参见此处。

尚未明确定义这些早期Netscape语言特性何时和是否将被弃用,或者严格模式是否会在某个时候成为浏览器中的默认行为,但更严格的模式可能会产生更少的歧义和风险源。如果您希望在编码实践和代码库中提高可维护性、可移植性和可扩展性,则严格模式是一个不错的选择。


注意 对于那些从“在每个文件中使用'function() 'use strict'”有什么好处?来到这里的人

您可以放置

"use strict";

代码序列的顶部或函数内部,所以每个文件或每个函数只有一行代码。

这里的其他代码行有其他目的。 在这里

  • 自调用函数
  • 工厂调用

有些人将整个文件放在自执行函数中,但并非每种情况都需要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接