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

我查看了 Mozilla Developer Network上的 JavaScript 引用,发现了一个叫做 "strict mode"的东西。我看了一遍,我不明白它是干什么的。有人能简要地(一般地)解释一下它的目的是什么以及它是如何有用的吗?

74336 次浏览

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

只要在代码的顶部添加 "use strict";,就可以了。

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

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

大多数时候 并不意味着在任意范围内创建全局变量,所以大多数时候编写 blah = 33是一个错误,程序员实际上并不希望它是一个全局变量,他们意味着编写 var blah = 33

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

请在严格模式 的 MDN 页面上阅读更多内容。

增加了严格的模式,这样就会有一个易于静态分析的 ECMAScript子集,这将是语言未来版本的一个很好的目标。严格模式的设计还希望那些将自己限制在严格模式下的开发人员会犯更少的错误,并且他们所犯的错误会以更明显的方式显现出来。

Harmony 有望成为 ECMAScript 的下一个主要版本,它将构建在 ES5的严格基础之上。

和谐建立在 ES5的严格模式,以避免太多的模式。

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

安全 ECMAScript 设计实验

通过删除或修复 ES5中的特性设计一种对象能力编程语言。

应该有一个直接的翻译从 SES 到 ES5/严格。

标准附件 C 解释了严格模式和普通模式的区别。

严格的模式限制和例外

  • 在严格的模式代码中,标识符“恶意”、“接口”、“让”、“包”、“私有”、“保护”、“公共”、“静态”和“产量”被分类为 FutureReserve Word 令牌。(7.6.12[ ? ]).
  • 在处理严格模式代码时,符合规范的实现可能不会扩展 NumericLiteral (7.8.3)的语法以包含 B.1.1中描述的 OctalIntegerLiteral。
  • 在处理严格模式代码(参见10.1.1)时,符合规范的实现可能不会像 B.1.2中描述的那样扩展 EscapeSequence 的语法以包含 OctalEscapeSequence。
  • 对未声明标识符或其他不可解析引用的赋值不会在全局对象中创建属性。当简单赋值在严格模式代码中发生时,其 LeftHandSide 不能计算为无法解析的 Reference。如果执行此操作,将引发 ReferenceError 异常(8.7.2)。LeftHandSide 也不能引用属性值为{[[ Writable ]] : false }的数据属性,不能引用属性值为{[[ Set ]] : unDefinition }的访问器属性,也不能引用内部属性值为 false 的对象的不存在属性。在这些情况下,会引发 TypeError 异常(11.13.1)。
  • 标识符 eval 或参数不能显示为分配操作符(11.13)或 PostfixExpression (11.3)的 LeftHandSideExpression,也不能显示为由前缀增量(11.4.4)或前缀减量(11.4.5)操作的 UnaryExpression。 严格模式函数的参数对象定义名为“调用方”和“被调用方”的非配置访问器属性,这些属性在访问时抛出 TypeError 异常(10.6)。
  • 严格模式函数的参数对象不会与其函数的相应形式参数绑定动态共享其数组索引属性值。(10.6). 对于严格模式函数,如果创建了参数对象,则局部标识符参数与参数对象的绑定是不可变的,因此可能不是赋值表达式的目标。(10.5).
  • 如果严格模式代码包含一个 ObjectLiteral,其中包含任何数据属性(11.1.5)的多个定义,则为 SyntaxError。 如果标识符“ eval”或标识符“局部参数”作为 Property 赋值的 PropertySetParameter terList 中的标识符出现,并且包含在严格的代码中,或者它的 FunctionBody 是严格的代码(11.1.5) ,那么它就是一个 SyntaxError。
  • 严格模式的 eval 代码不能在要 eval 的调用者的变量环境中实例化变量或函数。相反,将创建一个新的变量环境,并将该环境用于 eval 代码的声明绑定实例化(10.4.2)。
  • 如果在严格模式代码中计算此值,则此值不会强制为对象。空值或未定义的此值不转换为全局对象,基元值不转换为包装器对象。通过函数调用传递的 this 值(包括使用 Function.Prototype.application 和 Function.Prototype.call 进行的调用)不会强制将 this 值传递给对象(10.4.3,11.1.1.15.3.4.3,15.3.4.4)。
  • 当删除操作符出现在严格模式代码中时,如果其 UnaryExpression 是对变量、函数参数或函数名(11.4.1)的直接引用,则会引发 SyntaxError。
  • 当删除操作符出现在严格模式代码中时,如果要删除的属性具有属性{[[[ Configable ]] : false }(11.4.1) ,则会引发 TypeError。 如果 VariableDeclaration 或 VariableDeclarationNoIn 出现在严格的代码中,并且其标识符是 eval 或参数(12.2.1) ,则为 SyntaxError。
  • 严格模式代码可能不包括 WithStatement。在这样的上下文中出现 WithStatement 是一个 SyntaxError (12.10)。
  • 如果在严格的代码中发生带有 Catch 的 TryStatement,并且 Catch 产品的标识符是 eval 或参数(12.14.1) ,则为 SyntaxError
  • 如果标识符 eval 或参数出现在严格模式 FunctionDeclaration 或 FunctionExpression (13.1)的 FormalParameter terList 中,则为 SyntaxError
  • 严格模式函数不能有两个或多个具有相同名称的形式参数。尝试使用 FunctionDeclaration、 FunctionExpression 或 Function 构造函数创建这样的函数是一个 SyntaxError (13.1,15.3.2)。
  • 实现不能扩展,超出本规范中定义的,命名为调用方的属性或函数实例的参数的严格模式函数中的含义。ECMAScript 代码不能在与严格模式函数(10.6,13.2,15.3.4.5.3)对应的函数对象上创建或修改具有这些名称的属性。
  • 在严格模式代码中使用标识符 eval 或参数作为 FunctionDeclaration 或 FunctionExpression 的标识符或作为形式参数名(13.1)是一个 SyntaxError。尝试使用函数构造函数(15.3.2)动态定义这样一个严格的模式函数将引发 SyntaxError 异常。

严格模式的一个方面在 Simon 的回答中没有提到,那就是在通过函数调用调用的函数中,严格模式将 this设置为 undefined

所以像这样的事情

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


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

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

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

  • 通过将某些 JavaScript 无声错误更改为抛出错误来消除这些错误。

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

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

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

严格模式是语言的一个子集,它排除了不推荐的特性 模式是 opt-in 而不是必需的,这意味着如果您希望您的代码在 您可以使用(每个函数一次,或者使用 整个程序)下面的字符串:

"use strict";

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

在代码中调用严格模式

严格模式适用于整个脚本或单个函数。它不适用于括在{}大括号中的块语句,试图将其应用于这样的上下文不会产生任何效果。

剧本:

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

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

严格的功能模式:

对于函数的 调用严格模式,在函数体的开始部分放置确切的语句“ use strong”; 在任何其他语句之前。

function yourFunc(){
"use strict";


// Your function code logic
}

严格模式合并了一些对正常 JavaScript 语义的更改。首先,严格模式通过将某些 JavaScript 无声错误更改为抛出错误,从而消除了这些错误。

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

Enter image description here

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

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

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


// Will not throw an error

使用严格模式的优点:

  • 通过抛出错误来消除 JavaScript 无声错误。
  • 修正了使 JavaScript 引擎难以执行优化的错误。
  • 使代码有时比不在严格模式下的相同代码运行得更快
  • 禁止在未来版本的 ECMAScript 中可能定义的某些语法。

2017年,我终于找到了文件:
Https://developer.mozilla.org/en-us/docs/web/javascript/reference/strict_mode

严格模式是选择使用受限 JavaScript 变体的一种方式。 严格模式不仅仅是一个子集: 它故意有不同的 语义。不支持严格模式的浏览器将 运行具有不同行为的严格模式代码,因此 不要依赖于没有特性测试的严格模式来支持 严格模式的相关方面。严格模式代码和非严格模式 代码可以共存,因此脚本可以逐步进入严格模式。


严格模式对正常的 JavaScript 语义进行了几处更改。 首先,通过严格模式消除一些 JavaScript 无声错误 第二,严格模式修复了错误 使 JavaScript 引擎难以执行优化: 严格模式代码有时可以使运行速度超过相同 不是严格模式的代码。第三,严格模式禁止某些语法 可能在 ECMAScript 的未来版本中定义。

问题:

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

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

使用以下 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'))
});

我得到的错误如下:

~/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...

解决方案:

因此,它显示了 index.js文件,这是在我的 Gulp-sass 模块(基本上是锁定的,不应该被编辑)。但是如果我强行将 "use_strict"添加到那个 index.js文件的顶部,它会平稳地运行我的任务。

我很无助,所以我一直用这个作为解决办法!但是,在浏览了其他堆栈溢出 问与答,我看到了以下答案之后,如下所示:

sudo npm install -g n
sudo n stable

当我更新我的 Node.js (版本10.x) ,然后通过运行以下命令作为 Terminal 重建 Gulp 时,它指示我:

npm rebuild node-sass --force

一切都会好起来的。所以就这么解决了。我已经撤消了对 index.js Gulp.js 模块文件所做的更改。现在一切都很顺利。

严格模式是 ECMAScript 5中的一个新特性,它允许开发人员将代码放在“严格”上下文中。 这种严格的上下文有助于开发人员通过抛出更多异常来避免错误。

如何在 js 中使用严格模式?

很简单。把它放在程序的顶部,就可以启用整个脚本了:

"use strict";

或者将它放在一个函数中,以便只在该上下文中打开严格模式。

function imStrict(){
"use strict";
// … your code (executes in strict mode) …
}

在 JS 中使用严格模式的优点

1. 函数是块内的块作用域 范围确定代码区域中变量或其他资源的可见性或可访问性

Case I (没有严格模式) enter image description here

案例 II (严格模式) enter image description here

2. 如果为变量赋值但未定义任何类型,则引发错误/异常 enter image description here 在上面的示例中,“ a”没有声明任何值(let、 const、 var)

3. 如果在本地使用任何保留变量,则引发错误 在严格模式下,为未来 JavaScript 版本保留的关键字不能用作变量名。

这些是: 公众人士 工具 接口 让 包裹 二等兵 受到保护 静电干扰 投降 例如,< img src = “ https://i.stack.imgur.com/KDE0M.png”alt = “ enter image description here”/> < img src = “ https://i.stack.imgur.com/KDE0M.png”alt = “在这里输入图像描述”

4. 简单函数中的“ this”在严格模式下指向“ unDefinition”。 “ this”关键字指的是称为函数的对象。 如果未指定对象,则严格模式下的函数将返回未定义的对象,而普通模式下的函数将返回全局对象(窗口) 下面是更好理解的例子

Case I (没有严格模式) enter image description here

案例 II (严格模式) enter image description here

5. 不允许删除变量(或对象)和函数。 enter image description here

6. 不允许复制参数名 enter image description here

默认情况下,类的主体以严格模式执行。 例如:

class Rectangle {
//code executed here are in Strict mode
}

参考文献

  1. John Resig
  2. MDN
  3. W3学校