Javascript 什么是“严格模式”,它是如何使用的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8651415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:55:52  来源:igfitidea点击:

what is "strict mode" and how is it used?

javascriptstrict-mode

提问by nkcmr

I've been looking over the JavaScript reference on the Mozilla Developer Network, and I came across something called "strict mode". I read it over and I'm having trouble understanding what it does. Can someone briefly explain (in general) what its purpose is and how it is useful?

我一直在查看 Mozilla 开发人员网络上的 JavaScript 参考,我遇到了一个叫做"strict mode". 我读了一遍,但无法理解它的作用。有人可以简要解释(一般)它的目的是什么以及它是如何有用的?

回答by Simon Sarris

Its main purpose is to do more checking.

它的主要目的是做更多的检查。

Just add "use strict";at the top of your code, before anything else.

只需"use strict";在代码顶部添加其他任何内容。

For example, blah = 33;is valid JavaScript. It means you create a completely global variable blah.

例如,blah = 33;是有效的 JavaScript。这意味着您创建了一个完全全局变量blah

But in strict mode its an error because you did not use the keyword "var" to declare the variable.

但是在严格模式下它是一个错误,因为您没有使用关键字“var”来声明变量。

Most of the timeyou don't mean to create global variables in the middle of some arbitrary scope, so most of the time that blah = 33is written it is an error and the programmer didn't actually want it to be a global variable, they meant to write var blah = 33.

大多数情况下,您并不是要在某个任意范围的中间创建全局变量,因此在大多数情况下blah = 33编写它是一个错误,并且程序员实际上并不希望它成为全局变量,他们的意思是写var blah = 33

It similarly disallows a lot of things that are technically valid to do. NaN = "lol"does not produce an error. It also doesn't change the value of NaN. using strict this (and similar weird statements) produce errors. Most people appreciate this because there is no reason to ever write NaN = "lol", so there was most likely a typo.

它同样不允许许多技术上有效的事情去做。NaN = "lol"不会产生错误。它也不会改变 NaN 的值。使用严格的 this(和类似的奇怪语句)会产生错误。大多数人欣赏这一点,因为没有理由写NaN = "lol",所以很可能是打字错误。

Read more at the MDN page on strict mode

在严格模式的 MDN 页面阅读更多信息

回答by Adam Rackis

One aspect of strict mode not already mentioned in Simon's answer is that strict mode sets thisto undefinedin functions invoked through function invocation.

Simon 的回答中没有提到的严格模式的一个方面是严格模式设置thisundefined通过函数调用调用的函数。

So things like this

所以像这样的事情

function Obj() {
   this.a = 12;
   this.b = "a";
   this.privilegedMethod = function () {
      this.a++;
      privateMethod();
   };

   function privateMethod() {
     this.b = "foo";
   }
}

will cause an error when privateMethodis called (since you can't add a property to undefined), rather than uselessly adding a bproperty to the global object.

privateMethod调用时会导致错误(因为您无法向 中添加属性undefined),而不是无用地向b全局对象添加属性。

回答by Mike Samuel

Strict mode was added so that there would be an easily statically-analyzable subset of EcmaScript which would be a good target for future versions of the language. Strict mode was also designed in the hope that developers who limit themselves to strict mode would make fewer mistakes and that the bugs they do make would manifest in more obvious ways.

添加了严格模式,以便有一个易于静态分析的 EcmaScript 子集,这将是该语言未来版本的良好目标。严格模式的设计也是希望将自己限制在严格模式的开发人员犯的错误更少,并且他们所犯的错误会以更明显的方式表现出来。

Harmony, which will hopefully become the next major version of EcmaScript is going to be built on top of ES5 strict.

Harmony有望成为 EcmaScript 的下一个主要版本,它将建立在 ES5 strict 之上。

Harmony builds on ES5 strict mode to avoid too many modes.

Harmony 建立在 ES5 严格模式上,以避免模式过多。

Some other language experiments also depend on strict mode. SESdepends on ES5 strict mode's analyzability.

其他一些语言实验也依赖于严格模式。 SES依赖于 ES5 严格模式的可分析性。

SES (Secure ECMAScript) Design Experiment

Design an Object Capability Programming Language by removing or repairing features in ES5/Strict.

There should be a straight-forward translation from SES to ES5/Strict.

SES (Secure ECMAScript) 设计实验

通过删除或修复 ES5/Strict 中的功能来设计对象能力编程语言。

应该有从 SES 到 ES5/Strict 的直接转换。

Annex Cof the standard explains the differences between strict mode and normal mode.

标准的附录 C解释了严格模式和正常模式之间的区别。

The strict mode restriction and exceptions

  • The identifiers "implements", "interface", "let", "package", "private", "protected", "public", "static", and "yield" are classified as FutureReservedWord tokens within strict mode code. (7.6.12 [?]).
  • A conforming implementation, when processing strict mode code, may not extend the syntax of NumericLiteral (7.8.3) to include OctalIntegerLiteral as described in B.1.1.
  • A conforming implementation, when processing strict mode code (see 10.1.1), may not extend the syntax of EscapeSequence to include OctalEscapeSequence as described in B.1.2.
  • Assignment to an undeclared identifier or otherwise unresolvable reference does not create a property in the global object. When a simple assignment occurs within strict mode code, its LeftHandSide must not evaluate to an unresolvable Reference. If it does a ReferenceError exception is thrown (8.7.2). The LeftHandSide also may not be a reference to a data property with the attribute value {[[Writable]]:false}, to an accessor property with the attribute value {[[Set]]:undefined}, nor to a non-existent property of an object whose [[Extensible]] internal property has the value false. In these cases a TypeError exception is thrown (11.13.1).
  • The identifier eval or arguments may not appear as the LeftHandSideExpression of an Assignment operator (11.13) or of a PostfixExpression (11.3) or as the UnaryExpression operated upon by a Prefix Increment (11.4.4) or a Prefix Decrement (11.4.5) operator. Arguments objects for strict mode functions define non-configurable accessor properties named "caller" and "callee" which throw a TypeError exception on access (10.6).
  • Arguments objects for strict mode functions do not dynamically share their array indexed property values with the corresponding formal parameter bindings of their functions. (10.6). For strict mode functions, if an arguments object is created the binding of the local identifier arguments to the arguments object is immutable and hence may not be the target of an assignment expression. (10.5).
  • It is a SyntaxError if strict mode code contains an ObjectLiteral with more than one definition of any data property (11.1.5). It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code or if its FunctionBody is strict code (11.1.5).
  • Strict mode eval code cannot instantiate variables or functions in the variable environment of the caller to eval. Instead, a new variable environment is created and that environment is used for declaration binding instantiation for the eval code (10.4.2).
  • If this is evaluated within strict mode code, then the this value is not coerced to an object. A this value of null or undefined is not converted to the global object and primitive values are not converted to wrapper objects. The this value passed via a function call (including calls made using Function.prototype.apply and Function.prototype.call) do not coerce the passed this value to an object (10.4.3, 11.1.1, 15.3.4.3, 15.3.4.4).
  • When a delete operator occurs within strict mode code, a SyntaxError is thrown if its UnaryExpression is a direct reference to a variable, function argument, or function name(11.4.1).
  • When a delete operator occurs within strict mode code, a TypeError is thrown if the property to be deleted has the attribute { [[Configurable]]:false } (11.4.1). It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code and its Identifier is eval or arguments (12.2.1).
  • Strict mode code may not include a WithStatement. The occurrence of a WithStatement in such a context is an SyntaxError (12.10).
  • It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the Catch production is eval or arguments (12.14.1)
  • It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1)
  • A strict mode function may not have two or more formal parameters that have the same name. An attempt to create such a function using a FunctionDeclaration, FunctionExpression, or Function constructor is a SyntaxError (13.1, 15.3.2).
  • An implementation may not extend, beyond that defined in this specification, meanings within strict mode functions of properties named caller or arguments of function instances. ECMAScript code may not create or modify properties with these names on function objects that correspond to strict mode functions (10.6, 13.2, 15.3.4.5.3).
  • It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the Identifier of a FunctionDeclaration or FunctionExpression or as a formal parameter name (13.1). Attempting to dynamically define such a strict mode function using the Function constructor (15.3.2) will throw a SyntaxError exception.

严格模式限制和例外

  • 标识符“implements”、“interface”、“let”、“package”、“private”、“protected”、“public”、“static”和“yield”在严格模式代码中被归类为 FutureReservedWord 标记。(7.6.12 [?])。
  • 在处理严格模式代码时,符合要求的实现可能不会扩展 NumericLiteral (7.8.3) 的语法以包含如 B.1.1 中所述的 OctalIntegerLiteral。
  • 在处理严格模式代码(见 10.1.1)时,一个符合要求的实现可能不会扩展 EscapeSequence 的语法以包含如 B.1.2 中描述的 OctalEscapeSequence。
  • 分配给未声明的标识符或其他无法解析的引用不会在全局对象中创建属性。当在严格模式代码中发生简单赋值时,其 LeftHandSide 不得评估为无法解析的引用。如果确实如此,则会引发 ReferenceError 异常(8.7.2)。LeftHandSide 也可能不是对属性值为 {[[Writable]]:false} 的数据属性的引用、对属性值为 {[[Set]]:undefined} 的访问器属性的引用,也可能不是对不存在的引用[[Extensible]] 内部属性值为 false 的对象的属性。在这些情况下,会抛出 TypeError 异常 (11.13.1)。
  • 标识符 eval 或参数不能作为赋值运算符 (11.13) 或 PostfixExpression (11.3) 的 LeftHandSideExpression 或作为由前缀增量 (11.4.4) 或前缀减量 (11.4.5) 运算符操作的一元表达式出现. 严格模式函数的参数对象定义名为“caller”和“callee”的不可配置访问器属性,它们在访问时抛出 TypeError 异常(10.6)。
  • 严格模式函数的参数对象不会与其函数的相应形式参数绑定动态共享其数组索引属性值。(10.6)。对于严格模式函数,如果创建了参数对象,则本地标识符参数与参数对象的绑定是不可变的,因此可能不是赋值表达式的目标。(10.5)。
  • 如果严格模式代码包含具有多个数据属性定义的 ObjectLiteral (11.1.5),则为 SyntaxError。如果标识符“eval”或标识符“arguments”作为包含在严格代码中的 PropertyAssignment 的 PropertySetParameterList 中的标识符出现,或者它的 FunctionBody 是严格代码 (11.1.5),则它是 SyntaxError。
  • 严格模式 eval 代码不能实例化调用者变量环境中的变量或函数来进行 eval。相反,会创建一个新的变量环境,并且该环境用于 eval 代码 (10.4.2) 的声明绑定实例化。
  • 如果在严格模式代码中计算 this,则 this 值不会被强制转换为对象。null 或 undefined 的 this 值不会转换为全局对象,并且原始值不会转换为包装器对象。通过函数调用(包括使用 Function.prototype.apply 和 Function.prototype.call 进行的调用)传递的 this 值不会强制将传递的 this 值传递给对象 (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4)。
  • 当删除运算符出现在严格模式代码中时,如果其 UnaryExpression 是对变量、函数参数或函数名称 (11.4.1) 的直接引用,则会引发 SyntaxError。
  • 当删除操作符出现在严格模式代码中时,如果要删除的属性具有属性 { [[Configurable]]:false } (11.4.1),则会抛出 TypeError。如果 VariableDeclaration 或 VariableDeclarationNoIn 出现在严格代码中并且其标识符是 eval 或 arguments (12.2.1),则为 SyntaxError。
  • 严格模式代码可能不包含 WithStatement。在这种上下文中出现 WithStatement 是 SyntaxError (12.10)。
  • 如果在严格代码中出现带有 Catch 的 TryStatement 并且 Catch 产生式的标识符是 eval 或 arguments (12.14.1),那么它是一个 SyntaxError
  • 如果标识符 eval 或 arguments 出现在严格模式 FunctionDeclaration 或 FunctionExpression (13.1) 的 FormalParameterList 中,则为 SyntaxError
  • 严格模式函数不能有两个或多个同名的形参。尝试使用 FunctionDeclaration、FunctionExpression 或 Function 构造函数创建这样的函数是 SyntaxError (13.1, 15.3.2)。
  • 除了本规范中定义的之外,实现可能不会扩展名为 caller 的属性或函数实例的参数的严格模式函数中的含义。ECMAScript 代码不得在与严格模式函数(10.6、13.2、15.3.4.5.3)对应的函数对象上创建或修改具有这些名称的属性。
  • 在严格模式代码中使用标识符 eval 或 arguments 作为 FunctionDeclaration 或 FunctionExpression 的标识符或作为形式参数名称 (13.1) 是 SyntaxError 。尝试使用 Function 构造函数 (15.3.2) 动态定义这样的严格模式函数将引发 SyntaxError 异常。

回答by Nishant Kumar

ECMAScript 5 introduced the concept of strict mode.

ECMAScript 5 引入了严格模式的概念。

Invoking Strict Mode in Code

在代码中调用严格模式

Strict mode applies to entire scripts or to individual function. It doesn't apply to block statement enclosed in {} braces, attempting to apply it to such contexts does nothing.

严格模式适用于整个脚本或单个函数。它不适用于括在 {} 大括号中的块语句,尝试将其应用于此类上下文没有任何作用。

Entire Script:

整个脚本:

Let say we are creating app.js so adding first statement use script will enforce strict mode for entire code.

假设我们正在创建 app.js,因此添加第一个语句 use 脚本将对整个代码强制执行严格模式。

// app.js whole script in strict mode syntax
“use strict”;
// Now you can start writing your code 

Strict mode for function:

函数的严格模式:

To Invoke strict mode for a function, put the exact statement “use strict”; in the start of function body before any other statement.

要为函数调用严格模式,请输入确切的语句“use strict”;在任何其他语句之前的函数体的开头。

function yourFunc(){
 "use strict";

 // Your function code logic
}

Strict mode incorporate several changes to normal Javascript semantics. First strict mode eliminate some JavaScript silent error by changing them to throw errors.

严格模式对普通 Javascript 语义进行了多项更改。第一个严格模式通过将它们更改为抛出错误来消除一些 JavaScript 静默错误。

For Instance: Code using Strict Mode

例如:使用严格模式的代码

enter image description here

在此处输入图片说明

In above code example without using strict mode in code It won't throw an error. As we are accessing variable xwithout declaring it. So in strict mode accessing undeclared variable throw an error.

在上面的代码示例中,没有在代码中使用严格模式不会抛出错误。因为我们正在访问变量x而不声明它。所以在严格模式下访问未声明的变量会抛出错误。

Now let's try to access variable x without declaring it without strict mode.

现在让我们尝试在没有严格模式的情况下访问变量 x 而不声明它。

(function(){
    x = 3;
})();

// Will not throw an error

Advantage of using strict mode:

使用严格模式的优点:

  • Eliminate JavaScript silent errors by throwing error.
  • Fixes mistake that make it difficult for JavaScript engine to perform optimisation.
  • Make code run faster sometime than identical code that's not in strict mode
  • Prohibits some syntax likely to be defined in future version of ECMAScript.
  • 通过抛出错误消除 JavaScript 静默错误。
  • 修复了导致 JavaScript 引擎难以执行优化的错误。
  • 使代码有时比非严格模式的相同代码运行得更快
  • 禁止某些可能在 ECMAScript 未来版本中定义的语法。

回答by Renganathan M G

Strict mode makes several changes to normal JavaScript semantics.

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

  • strict mode eliminates some JavaScript silent errors by changing them to throw errors.

  • strict mode fixes mistakes that make it difficult for JavaScript engines to perform optimizations.

  • strict mode prohibits some syntax likely to be defined in future versions of ECMAScript.

  • 严格模式通过将一些 JavaScript 静默错误更改为抛出错误来消除它们。

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

  • 严格模式禁止某些可能在 ECMAScript 未来版本中定义的语法。

回答by Vahid Hallaji

ECMAScript5introduces some new objects and properties and also the so-called "strict mode".

ECMAScript5引入了一些新的对象和属性以及所谓的"strict mode".

Strict mode is a subset of the language that excludes deprecated features. The strict mode is opt-in and not required, meaning that if you want your code to run in the strict mode, you declare your intention using (once per function, or once for the whole program) the following string:

严格模式是该语言的一个子集,它排除了不推荐使用的功能。严格模式是可选的,不是必需的,这意味着如果您希望代码在严格模式下运行,您可以使用(每个函数一次,或整个程序一次)以下字符串声明您的意图:

"use strict";

回答by Tilak Maddy

2017 and I finally found the documentation:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

2017 年,我终于找到了文档:https:
//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Strict mode is a way to opt in to a restricted variant of JavaScript. Strict mode isn't just a subset: it intentionally has different semantics from normal code. Browsers not supporting strict mode will run strict mode code with different behavior from browsers that do, so don't rely on strict mode without feature-testing for support for the relevant aspects of strict mode. Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally.

严格模式是一种选择加入受限制的 JavaScript 变体的方法。严格模式不仅仅是一个子集:它有意具有与普通代码不同的语义。不支持严格模式的浏览器将运行与支持严格模式的浏览器具有不同行为的严格模式代码,因此不要依赖严格模式而不进行功能测试来支持严格模式的相关方面。严格模式代码和非严格模式代码可以共存,因此脚本可以增量地选择进入严格模式。



Strict mode makes several changes to normal JavaScript semantics. First, strict mode eliminates some JavaScript silent errors by changing them to throw errors. Second, strict mode fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that's not strict mode. Third, strict mode prohibits some syntax likely to be defined in future versions of ECMAScript.

严格模式对正常的 JavaScript 语义进行了一些更改。首先,严格模式通过将一些 JavaScript 静默错误更改为抛出错误来消除它们。其次,严格模式修复了使 JavaScript 引擎难以执行优化的错误:严格模式代码有时可以比非严格模式的相同代码运行得更快。第三,严格模式禁止某些可能在 ECMAScript 未来版本中定义的语法。

回答by Randika Vishman

Question:
Following is the problem I encountered, I was following a tutorial and it ended up trying to compile following scssfile and trying to generate CSS code from it,

问题:
以下是我遇到的问题,我正在学习一个教程,它最终尝试编译以下scss文件并尝试从中生成 CSS 代码,

.fatty{
  width: percentage(6/7);
}

using following gulpfile.jstask:

使用以下gulpfile.js任务:

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    return gulp.src('app/scss/styles.scss')
        .pipe(sass())
        .pipe(gulp.dest('app/css'))
});

So the error I'm getting is as follows:

所以我得到的错误如下:

~/htdocs/Learning/gulp1/node_modules/gulp-sass/index.js:66
    let sassMap;
    ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
// stacktrace here...

Solution:
So it shows me index.jsfile which is inside my gulp-sass module (which is basically locked and shouldn't be edited). But if I go forcefully and add the "use_strict"on the top of that index.jsfile, it runs my task smoothly.

解决方案:
所以它向我显示了index.js我的 gulp-sass 模块中的文件(它基本上被锁定并且不应该被编辑)。但是,如果我强行"use_strict"在该index.js文件的顶部添加,它会顺利运行我的任务。

I was helpless, so I keep using this as the solution! But then after going through some other SO Q&A's I saw following answeras follows:

我很无助,所以我一直用这个作为解决方案!但是在经历了其他一些 SO Q&A 之后,我看到以下答案如下:

sudo npm install -g n
sudo n stable

and sooner I updated my NodeJs (to Version10.x), and then rebuilt Gulp by running following commands as Terminal instructed me:

我很快更新了我的 NodeJs(到 Version10.x),然后按照终端的指示运行以下命令来重建 Gulp:

npm rebuild node-sass --force

And it's all okay. So that's how it got resolved. I undone the changes I did for index.jsgulp module file. And now it runs smoothly.

一切都好。所以就这样解决了。我撤消了对index.jsgulp 模块文件所做的更改。现在它运行顺利。

Hope this answer will be helpful to someone out there!

希望这个答案对那里的人有所帮助!