“严格使用”在JavaScript中有什么作用,其背后的原因是什么?

JavaScript

西门小小

2020-03-09

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

第1行第1个字符处的问题:缺少“使用严格”语句。

通过搜索,我意识到有些人将"use strict";其代码添加到了JavaScript中。添加语句后,错误停止出现。不幸的是,谷歌没有透露此字符串语句背后的许多历史。当然,它一定与浏览器如何解释JavaScript有关,但是我不知道会有什么影响。

那么到底是"use strict";什么,它意味着什么,并且仍然有意义?

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

第134篇《“严格使用”在JavaScript中有什么作用,其背后的原因是什么?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

19个回答
路易Stafan 2020.03.09

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

请检查以下以非严格模式编写的功能:

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

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

神无宝儿 2020.03.09

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

  • “严格使用”指令是ECMAScript版本5中的新增功能。
  • 它不是语句,而是文字表达,被早期JavaScript版本忽略。
  • “使用严格”的目的是指示应在“严格模式”下执行代码。
  • 在严格模式下,例如,您不能使用未声明的变量。

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

坏处

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

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

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

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

哎小爱 2020.03.09

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

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

gia 2020.03.09

Use Strict用于显示常见和重复的错误,以便对它进行不同的处理,并更改java脚本的运行方式,例如:

  • 防止意外的全局变量

  • 没有重复

  • 消除

  • 消除这种胁迫

  • 更安全的eval()

  • 不可变的错误

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

神奇猴子 2020.03.09

use strict是一种使代码更安全的方法,因为您不能使用无法正常使用的危险功能。而且,如前所述,它使代码更加严格。

凯Harry 2020.03.09

JavaScript “strict” mode was introduced in ECMAScript 5.

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

Writing "use strict"; at the very top of your JS file turns on strict syntax checking. It does the following tasks for us:

  1. shows an error if you try to assign to an undeclared variable

  2. stops you from overwriting key JS system libraries

  3. forbids some unsafe or error-prone language features

use strict also works inside of individual functions. It is always a better practice to include use strict in your code.

浏览器兼容性问题:“使用”指令旨在向后兼容。不支持它们的浏览器只会看到未进一步引用的字符串文字。因此,他们将越过它并继续前进。

Sam神乐番长 2020.03.09

Note that use strict was introduced in EcmaScript 5 and was kept since then.

Below are the conditions to trigger strict mode in ES6 and ES7:

  • Global code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1.1).
  • Module code is always strict mode code.
  • All parts of a ClassDeclaration or a ClassExpression are strict mode code.
  • Eval code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct eval (see 12.3.4.1) that is contained in strict mode code.
  • 如果在严格模式代码中包含相关的FunctionDeclaration,FunctionExpression,GeneratorDeclaration,GeneratorExpression,MethodDefinition或ArrowFunction,或者如果产生该函数的[[ECMAScriptCode]]内部插槽值的代码以伪指令开头,功能代码为严格模式代码。包含“使用严格”指令。
  • 如果最后一个参数是一个字符串,则该函数代码将作为内置函数和生成器构造函数的参数提供给函数代码,该字符串在处理时是一个功能主体,该主体以包含使用严格指令的指令序言开头。
十三泡芙 2020.03.09

“使用严格”;ECMA致力于使JavaScript更加强大。它引入了JS使其至少有点“严格”的尝试(自90年代以来其他语言都实施了严格的规则)。实际上,它“迫使” JavaScript开发人员遵循某种编码最佳实践。不过,JavaScript非常脆弱。没有诸如类型变量,类型方法之类的东西。我强烈建议JavaScript开发人员学习更健壮的语言(例如Java或ActionScript3),并在JavaScript代码中实现相同的最佳实践,它将更好,更容易地工作。调试。

达蒙武藏 2020.03.09

ECMAScript委员会中的一些人有一个很好的演讲:JavaScript的变化,第1部分:ECMAScript 5“,关于增量使用"use strict"开关如何使JavaScript实现者能够清理JavaScript的许多危险特性而不会突然破坏每个网站在世界上。

当然,它也讨论了其中的许多错误特征以及ECMAScript 5如何修复它们。

蛋蛋飞云 2020.03.09

从w3schools报价

“严格使用”指令

“严格使用”指令是JavaScript 1.8.5(ECMAScript版本5)中的新增功能。

它不是语句,而是文字表达,被早期JavaScript版本忽略。

“使用严格”的目的是指示应在“严格模式”下执行代码。

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

为什么选择严格模式?

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

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

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

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

在严格模式下,对不可写属性,仅吸气剂属性,不存在属性,不存在变量或不存在对象的任何赋值都会引发错误。

请参考http://www.w3schools.com/js/js_strict.asp了解更多信息

樱理查德 2020.03.09

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

null 2020.03.09

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

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

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

现代JavaScript实践应始终唤起“使用严格”的原则;实用 ECMA集团将“严格”模式设为可选的唯一原因是,允许经验不足的编码人员访问JavaScript,然后给予时间以适应新的更安全的编码实践。

凯斯丁 2020.03.09

严格模式对常规JavaScript语义进行了几处更改:

  • 通过将它们更改为引发错误来消除一些JavaScript静默错误。

  • 修复了使JavaScript引擎难以执行优化的错误。

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

有关更多信息,请访问严格模式-Javascript

蛋蛋L西里 2020.03.09

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

  • 从而为未来的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不再是这种情况

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

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

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

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

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

资料来源:

null 2020.03.09

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

该命令周围的引号确保该代码在旧版本的浏览器中也仍然可以运行(尽管在严格模式下生成语法错误的内容通常只会导致脚本在旧版本的浏览器中以某种难以检测的方式发生故障)。

null 2020.03.09

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

您可以参考MDN文档以获取更多信息。

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

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

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

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

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

  • 您不能with在严格模式下使用-statement。
  • 在严格模式下,必须声明所有变量:如果将值分配给尚未声明为变量,函数,函数参数,子句参数或全局属性的标识符,Object则将获得ReferenceError在正常模式下,标识符隐式声明为全局变量(作为global的属性Object
  • 在严格模式下,关键字在作为函数(而不是方法)调用的函数中this具有值undefined(在正常模式下,this始终指向global Object)。此差异可用于测试实现是否支持严格模式:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • 同样,当使用call()apply在严格模式下调用this函数时,call()apply()调用的第一个参数的值也正是该值(在普通模式下nullundefined被全局Object对象和不是对象的值替换为对象。)

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

  • In strict mode, when passing code to eval(), you cannot declare or define variables or functions in the scope of the caller (as you can do it in normal mode). Instead, a new scope is created for eval() and the variables and functions are within that scope. That scope is destroyed after eval() finishes execution.
  • In strict mode the arguments-object of a function contains a static copy of the values, which are passed to that function. In normal mode the arguments-object has a somewhat "magical" behaviour: The elements of the array and the named function parameters reference both the same value.
  • In strict mode you will get a SyntaxError when the delete operator is followed by a non qualified identifier (a variable, function or function parameter). In normal mode the delete expression would do nothing and is evaluated to false.
  • In strict mode you will get a TypeError when you try to delete a non configurable property. (In normal mode the attempt simply fails and the delete expression is evaluated to false).
  • In strict mode it is considered a syntactical error when you try to define several properties with the same name for an object literal. (In normal mode there is no error.)
  • In strict mode it is considered a syntactical error when a function declaration has multiple parameters with the same name. (In normal mode there is no error.)
  • In strict mode octal literals are not allowed (these are literals that start with 0x. (In normal mode some implementations do allow octal literals.)
  • In strict mode the identifiers eval and arguments are treated like keywords. You cannot change their value, cannot assign a value to them, and you cannot use them as names for variables, functions, function parameters or identifiers of a catch block.
  • In strict mode are more restrictions on the possibilities to examine the call stack. arguments.caller and arguments.callee cause a TypeError in a function in strict mode. Furthermore, some caller- and arguments properties of functions in strict mode cause a TypeError when you try to read them.
西里Near 2020.03.09

这是ECMAScript 5的新功能。JohnResig 对此进行了很好的总结

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

"use strict";

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

蛋蛋L西里 2020.03.09

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

功能列表(非穷举)

  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. 严格模式不会arguments使用形式参数来别名对象的属性(即,function sum (a,b) { return arguments[0] + b;}工作中是因为arguments[0]绑定到a等等。)

  12. arguments.callee 不支持

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

null 2020.03.09

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

引用一些有趣的部分:

严格模式是ECMAScript 5中的一项新功能,可让您将程序或功能置于“严格”的操作环境中。这种严格的上下文会阻止采取某些措施,并引发更多异常。

和:

严格模式可以通过以下两种方式提供帮助:

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

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

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 

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

因此,我想它有点像"use strict"您可以在Perl中使用的(因此得名?):通过检测更多可能导致损坏的内容,它可以帮助您减少错误。

所有主要浏览器现在都支持严格模式

本机ECMAScript模块(带有importexport语句)和ES6类中,严格模式始终处于启用状态,不能被禁用。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android