“use strict”在 JavaScript 中有什么作用,背后的原因是什么?

What does "use strict" do in JavaScript, and what is the reasoning behind it?

提问人:Mark Rogers 提问时间:8/27/2009 最后编辑:Mark Rogers 更新时间:6/12/2023 访问量:1211260

问:

最近,我通过 Crockford 的 JSLint 运行了我的一些 JavaScript 代码,它给出了以下错误:

第 1 行字符 1 的问题:缺少“use strict”语句。

在进行一些搜索时,我意识到有些人会添加到他们的 JavaScript 代码中。添加语句后,错误停止出现。不幸的是,谷歌没有透露这个字符串语句背后的历史。当然,它一定与浏览器如何解释 JavaScript 有关,但我不知道效果会是什么。"use strict";

那么到底是怎么回事,它意味着什么,它仍然相关吗?"use strict";

当前是否有任何浏览器响应该字符串,或者它是否供将来使用?"use strict";

JavaScript 语法 jslint use-strict

评论

72赞 Benjamin Gruenbaum 9/6/2019
这里的答案是古老的,但它们是错误的。严格模式的主要原因不是为了防止编程错误 - 它是使 JavaScript 在词法范围内,以便它可以静态分析:]
3赞 Mikko Rantalainen 9/30/2022
奇怪的语法(魔术字符串作为语句)的原因是使其向后兼容较旧的 JavaScript 引擎。严格模式的想法是不允许一些有问题的 JavaScript 语言结构,但不改变代码的解释,因此无论 JavaScript 引擎是否实际支持严格模式,执行都是相同的。

答:

1426赞 seth 8/27/2009 #1

这是 ECMAScript 5 的一项新功能。约翰·雷西格(John Resig)对此做了一个很好的总结

它只是您放入 JavaScript 文件(位于文件顶部或函数内部)中的一个字符串,如下所示:

"use strict";

现在把它放在你的代码中应该不会对当前的浏览器造成任何问题,因为它只是一个字符串。如果您的代码违反了编译指示,则将来可能会导致您的代码出现问题。例如,如果你目前没有先定义,你的代码将开始失败......在我看来,这是一件好事。foo = "bar"foo

5481赞 Pascal MARTIN 8/27/2009 #2

ES6 模块更新

原生 ECMAScript 模块(带有 importexport 语句)和 ES6 类中,严格模式始终处于启用状态,无法禁用。

原始答案

这篇关于 Javascript 严格模式的文章可能会让您感兴趣: John Resig - ECMAScript 5 严格模式、JSON 等

引用一些有趣的部分:

严格模式是 ECMAScript 5 中的一项新功能,它允许您将程序或函数置于“严格”操作上下文中。这种严格的上下文会阻止执行某些操作,并引发更多异常。

和:

严格模式在以下几个方面有所帮助:

  • 它捕获了一些常见的编码漏洞,抛出异常。
  • 它可以防止或引发错误,当采取相对“不安全”的操作(例如获取对全局对象的访问权限)时。
  • 它禁用了令人困惑或考虑不周的功能。

另请注意,您可以将“严格模式”应用于整个文件...或者你可以只将它用于特定的功能(仍然引用 John Resig 的文章)

// Non-strict code...

(function(){
  "use strict";

  // Define your library strictly...
})();

// Non-strict code...

如果您必须混合新旧代码,这可能会有所帮助;-)

所以,我想这有点像你在Perl中使用的“使用严格”(因此得名?):它通过检测更多可能导致损坏的东西来帮助你减少错误。

现在,所有主流浏览器都支持严格模式。

76赞 Stephen 3/10/2012 #3

如果您使用去年左右发布的浏览器,那么它很可能支持 JavaScript 严格模式。只有在 ECMAScript 5 成为当前标准之前的旧浏览器才不支持它。

命令周围的引号确保代码在较旧的浏览器中仍然有效(尽管在严格模式下生成语法错误的事情通常只会导致脚本在这些较旧的浏览器中以某种难以检测的方式出现故障)。

484赞 Jamie Hutber 7/16/2012 #4

如果人们担心使用它,可能值得查看这篇文章:use strict

ECMAScript 5 浏览器中的“严格模式”支持。这是什么意思?
NovoGeek.com - 克里希纳的博客

它谈到了浏览器支持,但更重要的是如何安全地处理它:

function isStrictMode(){
    return !this;
} 
/*
   returns false, since 'this' refers to global object and 
   '!this' becomes false
*/

function isStrictMode(){   
    "use strict";
    return !this;
} 
/* 
   returns true, since in strict mode the keyword 'this'
   does not refer to global object, unlike traditional JS. 
   So here, 'this' is 'undefined' and '!this' becomes true.
*/
66赞 user2436758 6/1/2013 #5

“严格使用”;是一种保证,程序员不会使用 JavaScript 的松散或不良属性。它是一个指南,就像尺子会帮助你画直线一样。“使用严格”将帮助您进行“直接编码”。

那些不喜欢使用标尺来直行的人通常会在这些页面中要求其他人调试他们的代码。

相信我。与设计不佳的代码相比,开销可以忽略不计。Doug Crockford 已经担任了几年的高级 JavaScript 开发人员,他在这里发表了一篇非常有趣的文章。就我个人而言,我喜欢一直回到他的网站,以确保我不会忘记我的良好做法。

现代 JavaScript 实践应该始终唤起“使用严格”;ECMA Group 将“严格”模式设置为可选模式的唯一原因是允许经验不足的编码人员访问 JavaScript,并有时间适应新的、更安全的编码实践。

167赞 Pank 7/6/2013 #6

我强烈建议每个开发人员现在就开始使用严格模式。有足够多的浏览器支持它,严格模式将合法地帮助我们避免我们甚至不知道您的代码中的错误。

显然,在初始阶段会出现我们以前从未遇到过的错误。为了获得全部收益,我们需要在切换到严格模式后进行适当的测试,以确保我们已经捕获了所有内容。当然,我们不只是输入代码并假设没有错误。因此,是时候开始使用这个非常有用的语言功能来编写更好的代码了。use strict

例如

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint 是由 Douglas Crockford 编写的调试器。只需粘贴您的脚本,它就会快速扫描代码中任何明显的问题和错误。

262赞 DWoldrich 3/3/2014 #7

提醒大家,所有强硬的程序员:应用于现有代码可能是危险的!这东西不是什么让人感觉良好、快乐的贴纸,你可以在代码上拍打它以使其“更好”。使用编译指示,浏览器会突然在以前从未抛出的随机位置抛出异常,只是因为在那个位置你正在做一些默认/松散的 JavaScript 愉快地允许但严格的 JavaScript 憎恶的事情!代码中很少使用的调用中可能隐藏了严格性违规,这些调用只有在最终运行时才会引发异常 - 例如,在付费客户使用的生产环境中!"use strict""use strict"

如果你打算冒险,最好与全面的单元测试和严格配置的 JSHint 构建任务一起应用,这将使你有信心,你的模块没有黑暗的角落会因为你打开了严格模式而可怕地爆炸。或者,嘿,这是另一种选择:只是不要添加到任何遗留代码中,老实说,这样可能更安全。绝对不要添加到任何您不拥有或维护的模块中,例如第三方模块。"use strict""use strict""use strict"

我认为,即使它是一只致命的笼子动物,也可能是好东西,但你必须做对。严格的最佳时机是当您的项目是绿地并且您从头开始时。配置所有警告和选项,尽可能紧密地启动您的团队,获得一个好的构建/测试/断言系统,然后才开始将所有新模块标记为 .准备好纠正许多微不足道的错误和警告。通过将生成配置为 FAIL 来确保每个人都了解严重性,如果产生任何冲突。"use strict"JSHint/JSLintGrunt+Karma+Chai"use strict"JSHint/JSLint

当我采用时,我的项目不是一个绿地项目。结果,我的 IDE 充满了红色标记,因为我没有一半的模块,JSHint 对此表示抱怨。它提醒我,我将来应该做什么重构。由于我所有遗漏的陈述,我的目标是没有红标,但现在这已经是几年了。"use strict""use strict""use strict"

68赞 Renganathan M G 3/27/2014 #8

严格模式对正常的 JavaScript 语义进行了一些更改:

  • 通过更改一些 JavaScript 静默错误来消除它们 抛出错误。

  • 修复了使 JavaScript 变得困难的错误 引擎来执行优化。

  • 禁止将来可能定义的某些语法 ECMAScript 的版本。

欲了解更多信息,请访问严格模式 - Javascript

37赞 FutureNerd 3/29/2014 #9

ECMAScript 委员会的一些成员做了一个很好的演讲:对 JavaScript 的更改,第 1 部分:ECMAScript 5“,关于开关的增量使用如何允许 JavaScript 实现者清理 JavaScript 的许多危险特性,而不会突然破坏世界上的每一个网站。"use strict"

当然,它也谈到了这些错误功能是什么,以及 ECMAScript 5 是如何修复它们的。

59赞 Placeholder 9/5/2014 #10

从这一点开始,在所有敏感的 JavaScript 文件的开头包括在内是成为更好的 JavaScript 程序员并避免随机变量成为全局变量和事情悄无声息变化的一个小方法。use strict

101赞 2 revs, 2 users 69%Shubh #11

我的两分钱:

严格模式的目标之一是允许更快地调试问题。当某些错误的事情发生时,它通过抛出异常来帮助开发人员,这些事情可能导致你的网页的沉默和奇怪的行为。当我们使用时,代码会抛出错误,这有助于开发人员提前修复它。 use strict

使用后我学到的几件重要的事情: use strict

阻止全局变量声明:

"use strict";
var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

现在,此代码在全局范围内创建,可以使用 .当我们实现代码时,会抛出错误。nameoftreewindow.nameoftreeuse strict

未捕获的 ReferenceError:未定义 nameoftree

语句消除:

with不能使用 uglify-js 等工具缩小语句。它们也被弃用,并从未来的 JavaScript 版本中删除。

样本:

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000
};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
   // nameoftree = typeOfTree.name;

    for (var i = 0; i < 2; ++i) {
       // let(leafCount = i) { /*do something*/ }
    }
    for (var i = 0; i < 2; ++i) {
        with(leafCount = i) { /*do something*/ }
    }
};

var tree1 = new Tree(tree1Data);
console.log(window);

防止重复:

当我们有重复的属性时,它会抛出一个异常

未捕获的 SyntaxError:对象文本中没有重复的数据属性 在严格模式下允许

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

还有更多,但我需要获得更多的知识。

评论

0赞 Muhammad Ali 3/16/2023
第一个代码不起作用。
856赞 gprasant 11/25/2014 #12

该语句指示浏览器使用 Strict 模式,这是 JavaScript 的简化且更安全的功能集。"use strict";

功能列表(非详尽无遗)

  1. 不允许全局变量。(捕获变量名称中缺少的声明和拼写错误)var

  2. 静默失败的赋值将在严格模式下抛出错误(赋值NaN = 5;)

  3. 尝试删除不可删除的属性将抛出 (delete Object.prototype)

  4. 要求对象文本中的所有属性名称都是唯一的 (var x = {x1: "1", x1: "2"})

  5. 函数参数名称必须是唯一的 (function sum (x, x) {...})

  6. 禁止八进制语法(一些开发人员错误地认为前面的零不会改变数字。var x = 023;

  7. 禁止关键字with

  8. eval在严格模式下不会引入新变量

  9. 禁止删除纯名称 (delete x;)

  10. 禁止以任何形式绑定或转让名称evalarguments

  11. 严格模式不会使用形式参数来别名对象的属性。(例如,在 This works because is bound to 等。(请参阅下面的示例部分以了解差异argumentsfunction sum (a,b) { return arguments[0] + b;}arguments[0]a)

  12. arguments.callee不支持

[参考:严格模式Mozilla开发者网络]


例子:

  1. 严格模式代码不会为在其中创建的参数对象的属性添加别名
function show( msg ){
    msg = 42;
    console.log( msg );          // msg === 42
    console.log( arguments[0] ); // arguments === 42
}
show( "Hey" );

// In strict mode arguments[i] does not track the value of 
// the corresponding named argument, nor does a named argument track the value in the corresponding arguments[i]
function showStrict( msg ){
    "use strict";
    msg = 42;
    console.log( msg );          // msg === 42
    console.log( arguments[0] ); // arguments === "Hey"
}
showStrict( "Hey" );

评论

10赞 RobG 3/12/2021
以 11 为例。不清楚,不清楚严格模式有什么区别。
1赞 Donald Duck 10/28/2022
“不允许全局变量”的表述具有误导性。全局变量仍然可以通过使用 来使用,或者在全局范围内使用,或者通过赋值(显式使用),不允许通过执行 where 未声明(不显式使用 )来隐式添加属性。varletconstwindow.somethingwindowwindowsomething = somethingElsesomethingwindow
49赞 Heich-B 4/29/2015 #13

引用 w3schools 的话:

“use strict”指令

“use strict”指令是 JavaScript 1.8.5 (ECMAScript 版本 5)。

它不是一个语句,而是一个文字表达式,被前面忽略了 JavaScript 版本。

“use strict”的目的是表示代码应该是 在“严格模式”下执行。

例如,在严格模式下,不能使用未声明的变量。

为什么选择严格模式?

严格模式使编写“安全”JavaScript 变得更加容易。

严格模式将以前接受的“错误语法”更改为实际错误。

例如,在普通 JavaScript 中,错误键入变量名称会造成 一个新的全局变量。在严格模式下,这将引发错误, 使得不可能意外地创建全局变量。

在普通的 JavaScript 中,开发人员不会收到任何错误反馈 为不可写的属性赋值。

在严格模式下,对不可写属性的任何赋值 仅限 getter 属性、不存在的属性、不存在的属性 变量或不存在的对象将引发错误。

详情请参阅 http://www.w3schools.com/js/js_strict.asp

116赞 Ely 5/15/2015 #14

我想提供一个更有根据的答案来补充其他答案。我希望编辑最受欢迎的答案,但失败了。我试图使它尽可能全面和完整。

您可以参考 MDN 文档了解更多信息。

"use strict"ECMAScript 5 中引入的指令。

指令类似于语句,但又不同。

  • use strict不包含关键字:该指令是一个简单的表达式语句,它由一个特殊的字符串文字(单引号或双引号)组成。没有实现 ECMAScript 5 的 JavaScript 引擎只看到一个表达式语句,没有副作用。预计 ECMAScript 标准的未来版本将作为一个真正的关键词引入;因此,引号将过时。use
  • use strict只能在脚本或函数的开头使用,即它必须位于所有其他(实数)语句之前。它不一定是函数脚本中的第一条指令:它可以在前面包含由字符串文字组成的其他语句表达式(JavaScript 实现可以将它们视为特定于实现的指令)。字符串文字语句,在第一个实语句(在脚本或函数中)之后,是简单的表达式语句。解释者不得将其解释为指令,并且它们无效。

该指令指示以下代码(在脚本或函数中)是严格代码。 当脚本包含指令时,脚本最高级别的代码(不在函数中的代码)被视为严格代码。 当函数本身在严格代码中定义或函数包含指令时,函数的内容被视为严格代码。 传递给方法的代码在从严格代码调用或包含指令本身时被视为严格代码。use strictuse strictuse stricteval()eval()use strict

ECMAScript 5 的严格模式是 JavaScript 语言的一个受限子集,它消除了该语言的相关缺陷,并具有更严格的错误检查和更高的安全性。下面列出了严格模式和普通模式的区别(其中前三个尤为重要):

  • 不能在严格模式下使用 -语句。with
  • 在严格模式下,必须声明所有变量:如果将值赋给尚未声明为变量、函数、函数参数、catch-clause 参数或全局属性的标识符,则将得到一个 .在正常模式下,标识符被隐式声明为全局变量(作为全局变量的属性ObjectReferenceErrorObject)
  • 在严格模式下,关键字在作为函数(而不是方法)调用的函数中具有值。(在正常模式下,始终指向全局 )。这种差异可用于测试实现是否支持严格模式:thisundefinedthisObject
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • 此外,当使用 或 在严格模式下调用函数时,则恰好是 or 调用的第一个参数的值。(在正常模式下,由全局值替换,并且值(不是对象)被强制转换为对象。call()applythiscall()apply()nullundefinedObject

  • 在严格模式下,当您尝试为不可扩展对象分配只读属性或定义新属性时,将得到一个 。(在正常模式下,两者都会失败,而不会出现错误消息。TypeError

  • 在严格模式下,将代码传递给 时,不能在调用方的作用域中声明或定义变量或函数(就像在正常模式下一样)。相反,会创建一个新作用域,并且变量和函数都在该作用域内。完成执行后,该作用域将被销毁。eval()eval()eval()

  • 在严格模式下,函数的参数对象包含值的静态副本,这些值被传递给该函数。在正常模式下,arguments-object 具有某种“神奇”的行为:数组的元素和命名函数参数引用相同的值。

  • 在严格模式下,当运算符后跟非限定标识符(变量、函数或函数参数)时,你会得到一个。在正常模式下,表达式将不执行任何操作,并且计算结果为 。SyntaxErrordeletedeletefalse

  • 在严格模式下,当您尝试删除不可配置的属性时,您将得到一个。(在正常模式下,尝试会失败,表达式的计算结果为 )。TypeErrordeletefalse

  • 在严格模式下,当您尝试为对象文本定义具有相同名称的多个属性时,它被视为语法错误。(在正常模式下没有错误。

  • 在严格模式下,当函数声明具有多个同名参数时,它被视为语法错误。(在正常模式下没有错误。

  • 在严格模式下,不允许使用八进制文字(这些是以 . 开头的文字)。(在正常模式下,某些实现允许八进制文字。0

  • 在严格模式下,标识符 和 被视为关键字。您不能更改它们的值,不能为它们赋值,也不能将它们用作变量、函数、函数参数或 catch 块标识符的名称。evalarguments

  • 在严格模式下,对检查调用堆栈的可能性有更多限制。 并在严格模式下导致函数中出现。此外,严格模式下函数的某些 caller- 和 arguments 属性会在您尝试读取它们时导致 a。arguments.callerarguments.calleeTypeErrorTypeError

评论

6赞 Alex Gittemeier 8/12/2016
“在严格模式下,不允许使用八进制文字(这些是以 0x 开头的文字......)” 八进制文字以前导 .0
71赞 zangw 12/23/2015 #15

添加时,以下情况将在脚本执行之前抛出 SyntaxError"use strict";

  • 为将来的 ECMAScript 版本铺平道路,使用新保留的关键字之一(在 ECMAScript 6 的预备方案中):、、、、和 。implementsinterfaceletpackageprivateprotectedpublicstaticyield

  • 在块中声明函数

    if(a<b){ function f(){} }
    
  • 八进制语法

    var n = 023;
    
  • this指向全局对象。

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
    
  • 在对象文本中为属性名称声明两次相同的名称

     {a: 1, b: 3, a: 7} 
    

    在 ECMAScript 6 中不再出现这种情况(错误 1041128)。

  • 声明两个具有相同名称函数的函数参数 function

    f(a, b, b){}
    
  • 为未声明的变量设置值

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • 在变量名称上使用deletedelete myVariable;

  • 使用 或 作为变量或函数参数名称evalarguments

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 
    

来源:

评论

1赞 mdcq 1/12/2020
在 ECMAScript 2015 中,再次允许重复的属性名称!请参阅 MDN 文档
256赞 sampathsris 1/29/2016 #16

使用不会突然使您的代码变得更好。'use strict';

JavaScript 严格模式ECMAScript 5 中的一项功能。您可以通过在脚本/函数的顶部声明来启用严格模式。

'use strict';

当 JavaScript 引擎看到此指令时,它将开始以特殊模式解释代码。在这种模式下,当检测到某些最终可能成为潜在错误的编码实践时,就会抛出错误(这是严格模式背后的原因)。

请看这个例子:

var a = 365;
var b = 030;

由于痴迷于排列数字文字,开发人员无意中用八进制文字初始化了变量。非严格模式会将其解释为带有值的数字文字(以 10 为基数)。但是,严格模式会引发错误。b24

有关严格模式下的专业列表,请参阅此答案


我应该在哪里使用?'use strict';

  • 在我的 JavaScript 应用程序中:绝对!严格模式可以用作举报人,当您对代码做一些愚蠢的事情时。

  • 在我现有的 JavaScript 代码中:可能不是!如果现有的 JavaScript 代码包含严格模式下禁止的语句,则应用程序将中断。如果需要严格模式,则应准备好调试和更正现有代码。这就是为什么使用“use strict”不会突然使你的代码变得更好


如何使用严格模式?

  1. 在脚本顶部插入一条语句:'use strict';

     // File: myscript.js
    
     'use strict';
     var a = 2;
     ....
    

    请注意,文件中的所有内容都将在严格模式下解释。myscript.js

  2. 或者,在函数体的顶部插入一条语句:'use strict';

     function doSomething() {
         'use strict';
         ...
     }
    

    词法功能范围内的所有内容都将以严格模式进行解释。词汇范围这个词在这里很重要。例如,如果严格代码调用库的函数不严格,则只有代码在严格模式下执行,而不是被调用的函数。请参阅此答案以获得更好的解释。doSomething


严格模式下禁止哪些事情?

我找到了一篇很好的文章,描述了严格模式下禁止的几件事(请注意,这不是一个详尽的列表):

范围

从历史上看,JavaScript 一直对函数的运作方式感到困惑 已确定范围。有时它们似乎是静态范围的,但有些 功能使它们的行为就像是动态作用域一样。这是 令人困惑,使程序难以阅读和理解。 误解会导致错误。这也是性能问题。 静态作用域将允许在编译时进行变量绑定 时间,但对动态范围的要求意味着绑定必须 延迟到运行时,这带来了显着的性能 罚款。

严格模式要求所有变量绑定都是静态完成的。 这意味着以前需要动态绑定的功能 必须删除或修改。具体来说,with 语句是 消除,并且 eval 函数篡改 其调用方的环境受到严格限制。

严格代码的好处之一是,像 YUI Compressor 这样的工具在处理代码时可以做得更好。

隐含全局变量

JavaScript 隐含了全局变量。如果 你没有显式声明一个变量,一个全局变量是 隐式为您声明。这使得编程更容易 初学者,因为他们可以忽略一些基本的家务 家务。但它使大型项目的管理变得更加多 困难,它会显着降低可靠性。所以在严格 模式,则不再创建隐含的全局变量。你应该 显式声明所有变量。

全球泄漏

在许多情况下,可能会导致绑定到全局对象。例如,如果您忘记了 在调用构造函数时提供前缀, 构造函数将意外绑定到全局对象,因此 它不会初始化一个新对象,而是静默地 篡改全局变量。在这些情况下,严格模式将 而是绑定到 ,这将导致构造函数 而是抛出异常,允许大量检测到错误 早。thisnewthisthisundefined

嘈杂故障

JavaScript 一直具有只读属性,但您 在 ES5 的函数公开该功能之前,无法自行创建它们。如果尝试赋值 对于只读属性,它将以静默方式失败。该任务将 不更改属性的值,但程序将按以下方式进行 虽然它有。这是一种完整性隐患,可能导致程序 进入不一致状态。在严格模式下,尝试更改 只读属性将引发异常。Object.createProperty

八进制

数字的八进制(或以 8 为基数)表示非常 在 Word 的机器上进行机器级编程时很有用 大小是 3 的倍数。与 CDC 合作时需要八进制 6600 大型机,字大小为 60 位。如果你能阅读 八进制,你可以把一个词看成 20 位数字。表示两位数 操作码和一位数字标识 8 个寄存器之一。在 从机器代码到高级语言的缓慢过渡,它是 被认为可用于在编程语言中提供八进制形式。

在 C 中,一个极其不幸的八进制表示是 selected:前导零。所以在 C 中,表示 64,而不是 100,并且是 错误,而不是 8。更不幸的是,这种不合时宜的做法已经 复制到几乎所有现代语言中,包括 JavaScript,其中 它仅用于创建错误。它没有其他目的。所以在 严格模式,不再允许八进制形式。010008

等等

参数伪数组变得多一点 ES5 中的数组。在严格模式下,它会失去其 和 属性。这样就可以将您的传递给不受信任的人 在不放弃大量机密上下文的情况下编写代码。此外,还消除了函数的属性。calleecallerargumentsarguments

在严格模式下,函数文本中的重复键将产生 语法错误。一个函数不能有两个同名的参数。 函数不能具有与其名称相同的变量 参数。函数不能有自己的变量。现在,尝试对不可配置的属性会引发异常。原始 值不会隐式包装。deletedelete


未来 JavaScript 版本的保留字

ECMAScript 5 添加了保留字列表。如果将它们用作变量或参数,严格模式将抛出错误。保留字为:

implementsinterfaceletpackageprivateprotectedpublicstaticyield


延伸阅读

24赞 Oriol 4/12/2016 #17

请注意,这是在 EcmaScript 5 中引入的,并从那时起一直保留。use strict

以下是在 ES6 和 ES7 中触发严格模式的条件

  • 如果全局代码以包含“使用严格指令”的指令序言开头,则全局代码为严格模式代码(请参阅 14.1.1)。
  • 模块代码始终是严格模式代码。
  • ClassDeclarationClassExpression 的所有部分都是严格模式代码。
  • 如果 Eval 代码以包含 Use Strict 指令的指令 Prologue 开头,或者对 eval 的调用是包含在严格模式代码中的直接 eval(请参阅 12.3.4.1),则该代码是严格模式代码。
  • 如果关联的 FunctionDeclaration、FunctionExpression、GeneratorDeclaration、GeneratorExpression、MethodDefinition 或 ArrowFunction 包含在严格模式代码中,或者生成函数的 [[ECMAScriptCode]] 内部插槽值的代码以包含 Use Strict 指令的 Directive Prologue 开头,则函数代码为严格模式代码。
  • 如果最后一个参数是 String,则作为内置 Function 和 Generator 构造函数的参数提供的函数代码是严格模式代码,该 String 在处理时是以包含 Use Strict 指令的 Directive Prologue 开头的 FunctionBody
14赞 FilippoG 5/3/2016 #18

“严格使用”;是 ECMA 努力使 JavaScript 更加健壮。它引入了 JS,试图让它至少有点“严格”(自 90 年代以来,其他语言实施了严格的规则)。它实际上“迫使”JavaScript 开发人员遵循某种编码最佳实践。 尽管如此,JavaScript 还是非常脆弱的。没有类型化变量、类型化方法等。 我强烈建议 JavaScript 开发人员学习更健壮的语言,例如 Java 或 ActionScript3,并在您的 JavaScript 代码中实现相同的最佳实践,这样会更好工作,更易于调试。

17赞 Ivan 5/18/2016 #19

use strict是一种使代码更安全的方法,因为您不能使用可能无法按预期工作的危险功能。而且,正如之前所写的那样,它使代码更加严格。

33赞 Tân 8/22/2016 #20

要比较的小例子:

非严格模式:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

严格模式:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

非严格模式:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true

12赞 Wesam 10/17/2016 #21

Use Strict 用于显示常见和重复的错误,以便以不同的方式处理,并改变 java 脚本的运行方式,这些更改是:

  • 防止意外全局变量

  • 没有重复项

  • 消除

  • 消除这种胁迫

  • 更安全的 eval()

  • immutable 的错误

您也可以阅读本文了解详细信息

15赞 Rabin Pantha 11/11/2016 #22

JavaScript “严格”模式是在 ECMAScript 5 中引入的。

(function() {
  "use strict";
  your code...
})();

在 JS 文件的最顶部写入会打开严格 语法检查。它为我们执行以下任务:"use strict";

  1. 如果尝试分配给未声明的变量,则显示错误

  2. 阻止您覆盖关键的 JS 系统库

  3. 禁止某些不安全或容易出错的语言功能

use strict也适用于各个功能。最好将它包含在代码中。use strict

浏览器兼容性问题: “use”指令旨在向后兼容。不支持它们的浏览器只会看到一个字符串文字,而该字符串文字不会被进一步引用。所以,他们会越过它并继续前进。

18赞 Pritam Banerjee 11/18/2016 #23

开发人员应该使用的主要原因是:"use strict"

  1. 防止意外声明全局变量。using 将确保变量在使用前被声明。 例如:"use strict()"var

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
    
  2. 注意:该指令仅在脚本或函数的开头被识别。"use strict"
  3. 字符串不能用作变量:"arguments"

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. 将限制关键字作为变量的使用。尝试使用它们会引发错误。

简而言之,这将使你的代码不那么容易出错,反过来又会让你写出好的代码。

要了解更多信息,您可以参考此处

13赞 Bikash Chapagain 11/21/2016 #24

通常,JavaScript 不遵循严格的规则,因此增加了出错的机会。使用后,JavaScript 代码应遵循与其他编程语言一样严格的规则集,例如使用终止符、初始化前的声明等。"use strict"

如果使用,则应遵循一组严格的规则编写代码,从而减少错误和歧义的机会。"use strict"

44赞 Alireza 5/22/2017 #25

"use strict"使 JavaScript 代码在严格模式下运行,这基本上意味着在使用之前需要定义所有内容。使用严格模式的主要原因是避免意外全局使用未定义的方法。

同样在严格模式下,事情运行得更快,一些警告或静默警告会引发致命错误,最好始终使用它来制作更整洁的代码。

"use strict"在 ECMA5 中被广泛使用,在 ECMA6 中,它默认是 JavaScript 的一部分,因此如果您使用的是 ES6,则不需要添加它。

看看 MDN 的这些语句和示例:

“use strict”指令 “use strict”指令
是 JavaScript 1.8.5(ECMAScript 版本 5)。这不是一个声明,而是一个 文字表达式,被早期版本的 JavaScript 忽略。这 “use strict”的目的是指示代码应该是 在“严格模式”下执行。在严格模式下,您不能,例如, 使用未声明的变量。

使用“use strict”的示例: 函数的严格模式:
同样,要为 函数,把确切的语句“use strict”;(或“使用严格”;)在 函数的主体,在任何其他语句之前。

1)功能中的严格模式

 function strict() {
     // Function-level strict mode syntax
     'use strict';
     function nested() { return 'And so am I!'; }
     return "Hi!  I'm a strict mode function!  " + nested();
 }
 function notStrict() { return "I'm not strict."; }

 console.log(strict(), notStrict());

2)全脚本严格模式

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3) 分配给不可写的全局

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

你可以在 MDN 上阅读更多内容

8赞 Ashish 1/28/2019 #26

“严格使用”;定义 JavaScript 代码应在 “严格模式”。

  • “use strict”指令是 ECMAScript 版本 5 中的新指令。
  • 它不是一个语句,而是一个文字表达式,被前面忽略了 JavaScript 版本。
  • “use strict”的目的是表示代码应该是 在“严格模式”下执行。
  • 例如,在严格模式下,不能使用未声明的变量。

Internet Explorer 9 及更低版本外,所有现代浏览器都支持“使用严格”。

缺点

如果开发人员使用的库处于严格模式,但开发人员习惯于在正常模式下工作,则他们可能会对库调用一些无法按预期工作的操作。

更糟糕的是,由于开发人员处于正常模式,因此他们没有抛出额外错误的优势,因此错误可能会以静默方式失败。

此外,如上所述,严格模式会阻止您执行某些操作。

人们通常认为你一开始就不应该使用这些东西,但一些开发人员不喜欢这种约束,并希望使用语言的所有功能。

5赞 Jerin K Alexander 7/8/2019 #27

严格模式可以防止内存泄漏。

请检查以下以非严格模式编写的函数:

function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); // Stack Overflow

在这个函数中,我们使用一个在函数内部调用的变量。在内部,编译器将首先检查该特定函数作用域中是否有任何使用该特定名称声明的变量。由于编译器知道没有这样的变量,因此它将在外部作用域中进行检查。在我们的例子中,它是全局范围。同样,编译器理解在全局空间中也没有声明具有该名称的变量,因此它在全局空间中为我们创建了这样一个变量。从概念上讲,此变量将在全局范围内创建,并将在整个应用程序中可用。name

另一种情况是,变量是在子函数中声明的。在这种情况下,编译器会检查该变量在外部作用域(即父函数)中的有效性。只有这样,它才会签入全局空间并在那里为我们创建一个变量。 这意味着需要进行额外的检查。这将影响应用程序的性能。


现在让我们在严格模式下编写相同的函数。

"use strict"
function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); 

我们将收到以下错误。

Uncaught ReferenceError: name is not defined
at getname (<anonymous>:3:15)
at <anonymous>:6:5

在这里,编译器抛出引用错误。在严格模式下,编译器不允许我们在未声明变量的情况下使用该变量。因此,可以防止内存泄漏。此外,我们可以编写更优化的代码。

5赞 shuberman 7/10/2020 #28

严格模式消除了在非严格模式下会被忽略的错误,从而使 javascript “更安全”。

它是否被认为是最佳实践之一?

是的,在使用 javascript 时,它被认为是包含严格模式的最佳实践的一部分。这是通过在 JS 文件中添加以下代码行来完成的。

'use strict';

在您的代码中。

这对用户代理意味着什么?

指示代码应在严格模式下解释,向用户代理(如浏览器)指定它们应将代码按字面意思视为编写的代码,如果代码没有意义,则抛出错误。

例如:考虑在您的文件中您有以下代码:.js

场景1:[无严格模式]

var city = "Chicago"
console.log(city) // Prints the city name, i.e. Chicago

场景2:[无严格模式]

city = "Chicago"
console.log(city) // Prints the city name, i.e. Chicago

那么,为什么在这两种情况下都打印变量名称呢?

如果不打开严格模式,用户代理通常会对有问题的代码进行一系列修改,以试图使其有意义。从表面上看,这似乎是一件好事,事实上,在严格模式之外工作使人们可以在不完全确定所有细节的情况下涉足 JavaScript 代码。但是,作为一名开发人员,我不想在我的代码中留下任何错误,因为我知道它以后可能会回来咬我,而且我也只想写出好的代码。这就是严格模式的用武之地。

场景3:[严格模式]

'use strict';

city = "Chicago"
console.log(city) // Reference Error: asignment is undeclared variable city.

附加提示:要使用严格模式保持代码质量,您不需要一遍又一遍地编写此代码,尤其是在您有多个文件的情况下。您可以在规则中全局强制执行此规则,如下所示:.jseslint

文件名: .eslintrc.js

module.exports = {
    env: {
        es6: true
    },
    rules : {
        strict: ['error', 'global'],
        },
    };
    

好的,那么在严格模式下会阻止什么呢?

  • 在不声明变量的情况下使用变量将在严格模式下引发错误。这是为了防止无意中在整个应用程序中创建全局变量。印刷芝加哥的例子特别涵盖了这一点。

  • 在严格模式下,删除变量、函数或参数是禁忌。

    "use strict";
     function x(p1, p2) {}; 
     delete x; // This will cause an error
    
  • 在严格模式下不允许复制参数名称

     "use strict";
     function x(p1, p1) {};   // This will cause an error
    
  • 在严格模式下不允许使用 Javascript 语言中的保留字。这些词是实现接口、let、packages、private、protected、public。静态和屈服

如需更全面的列表,请查看此处的 MDN 文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

6赞 snnsnn 7/25/2021 #29

JavaScript 的设计和实现是匆忙完成的,因为浏览器大战和管理不善。结果,许多糟糕的设计决策、不直观的语法和令人困惑的语义进入了语言。严格模式旨在纠正其中一些错误。

但是,在不创建替代解释的情况下修复这些错误会破坏向后兼容性。因此,指令在将代码传达给程序员时创建了代码的替代解释。"use strict"

例如,关键字是指方法定义中的对象,例如其他语言。thisthisself

let o = {
  name: 'John Doe',
  sayName: function(){
    console.log(this.name);
  }
};

o.sayName(); // 'John Doe'

this在方法上下文之外没有目的,但所有 JavaScript 函数都有关键字,无论它们是否是方法:this

function run() {
  console.log(this);
}

run(); // Window

这里解析为全局对象,该对象没有意义且没有任何用途,因为全局对象在作用域中已经可用。this

在严格模式下,全局函数解析为 undefined,这是我们所期望的。this

"use strict"

function run() {
  console.log(this);
}

run(); // undefined

即使在严格模式下,有些错误也无法修复,因为语法应该对较旧的浏览器有效,因为它们忽略了指令。这是设计使然。"strict mode"

2赞 Amin Azimi 6/21/2022 #30

严格模式可在 V8 引擎中启用严格功能。一些功能的简短示例:

您可以通过编写以下内容来全局启用它:

'use strict'; // strict mode enabled!

您只需包含在函数中的每个函数:

let myfunc = () => {
  'use strict'; // strict mode enabled
  
   b = 0; // broke
}
  • 在使用变量之前,您必须声明一个变量(sane imo):
  var x;
  x = '0'; // ok
  y = '';  // not ok
  • ES6 功能已启用(这取决于浏览器),对于 Node v4+,这很重要。

  • 在某些情况下,性能会更好。

还有更多功能,请在此处查看更多!

0赞 moaz ahmad 6/12/2023 #31

此模式最初是在 E S5 中实现的,用于在 javascript 中启用严格模式。

  1. 它可以捕获常见的编码错误并提高代码质量
  2. 某些错误将转换为异常。因此,代码不会崩溃。
  3. 如果函数不是作为方法或构造函数调用的,则“this”的值保持不变
  4. 它阻碍了重复的参数名称,如函数(ax,de,ax)。这在严格模式下是不允许的。

除此之外,严格模式还有许多功能,使用它对于创建复杂的代码是必要的。