我一直在查看Mozilla Developer Network上的 JavaScript 参考资料,并且遇到了一个名为"strict mode"
. 我读了一遍,我无法理解它的作用。有人可以简要解释(一般而言)它的目的是什么以及它是如何有用的吗?
9 回答
它的主要目的是做更多的检查。
只需"use strict";
在代码顶部添加,然后再添加。
例如,blah = 33;
是有效的 JavaScript。这意味着您创建了一个完全全局的变量blah
。
但在严格模式下这是一个错误,因为您没有使用关键字“var”来声明变量。
大多数情况下,您并不是要在某个任意范围的中间创建全局变量,因此大多数情况下blah = 33
编写它是一个错误,程序员实际上并不希望它成为全局变量,他们的意思是写var blah = 33
。
它同样不允许做很多技术上有效的事情。NaN = "lol"
不会产生错误。它也不会改变 NaN 的值。使用严格的 this(和类似的奇怪语句)会产生错误。大多数人对此表示赞赏,因为没有理由写NaN = "lol"
,所以很可能是错字。
西蒙的回答中尚未提到的严格模式的一个方面是严格模式设置this
为undefined
通过函数调用调用的函数。
所以像这样的事情
function Obj() {
this.a = 12;
this.b = "a";
this.privilegedMethod = function () {
this.a++;
privateMethod();
};
function privateMethod() {
this.b = "foo";
}
}
调用时会导致错误privateMethod
(因为您无法将属性添加到undefined
),而不是无用地向b
全局对象添加属性。
添加了严格模式,以便有一个易于静态分析的ECMAScript子集,这将是该语言未来版本的一个很好的目标。严格模式的设计也是希望限制自己的开发人员犯的错误更少,并且他们所犯的错误会以更明显的方式表现出来。
Harmony有望成为 ECMAScript 的下一个主要版本,它将构建在 ES5 strict 之上。
Harmony 建立在 ES5 严格模式之上,以避免过多的模式。
其他一些语言实验也依赖于严格模式。SES依赖于 ES5 严格模式的可分析性。
SES(安全 ECMAScript)设计实验
通过删除或修复 ES5/Strict 中的特性来设计对象能力编程语言。
应该有从 SES 到 ES5/Strict 的直接翻译。
标准的附录 C解释了严格模式和普通模式之间的区别。
严格模式限制和例外
- 标识符“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 或 arguments 不能显示为赋值运算符 (11.13) 或 PostfixExpression (11.3) 的 LeftHandSideExpression 或由前缀增量 (11.4.4) 或前缀减量 (11.4.5) 运算符操作的 UnaryExpression . 严格模式函数的参数对象定义了名为“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 异常。
ECMAScript 5 引入了严格模式的概念。
在代码中调用严格模式
严格模式适用于整个脚本或单个函数。它不适用于包含在 {} 大括号中的块语句,尝试将其应用于此类上下文不会执行任何操作。
整个脚本:
假设我们正在创建 app.js,因此添加第一个语句 use 脚本将为整个代码强制执行严格模式。
// app.js whole script in strict mode syntax
“use strict”;
// Now you can start writing your code
功能的严格模式:
要为函数调用严格模式,请输入确切的语句“use strict”;在任何其他语句之前的函数体的开头。
function yourFunc(){
"use strict";
// Your function code logic
}
严格模式包含对正常 JavaScript 语义的一些更改。首先,严格模式通过将它们更改为抛出错误来消除一些 JavaScript 静默错误。
例如:使用严格模式的代码
在上面的代码示例中,没有在代码中使用严格模式,它不会抛出错误。因为我们正在访问变量x
而不声明它。所以在严格模式下访问未声明的变量会引发错误。
现在让我们尝试访问一个变量 x,而不是在没有严格模式的情况下声明它。
(function(){
x = 3;
})();
// Will not throw an error
使用严格模式的好处:
- 通过抛出错误来消除 JavaScript 静默错误。
- 修复了使 JavaScript 引擎难以执行优化的错误。
- 使代码有时比非严格模式下的相同代码运行得更快
- 禁止某些可能在未来版本的 ECMAScript 中定义的语法。
严格模式对正常的 JavaScript 语义进行了一些更改。
严格模式通过将它们更改为抛出错误来消除一些 JavaScript 静默错误。
严格模式修复了使 JavaScript 引擎难以执行优化的错误。
严格模式禁止某些可能在未来版本的 ECMAScript 中定义的语法。
ECMAScript5
引入了一些新的对象和属性以及所谓的"strict mode"
.
严格模式是排除弃用功能的语言子集。严格模式是可选的,不是必需的,这意味着如果您希望代码在严格模式下运行,您可以使用以下字符串(每个函数一次,或整个程序一次)声明您的意图:
"use strict";
2017 年,我终于找到了文档:
https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
严格模式是一种选择加入 JavaScript 受限变体的方法。严格模式不仅仅是一个子集:它故意具有与普通代码不同的语义。不支持严格模式的浏览器将运行严格模式代码,其行为与支持的浏览器不同,因此不要依赖没有功能测试的严格模式来支持严格模式的相关方面。严格模式代码和非严格模式代码可以共存,因此脚本可以逐步选择进入严格模式。
严格模式对正常的 JavaScript 语义进行了一些更改。首先,严格模式通过将它们更改为抛出错误来消除一些 JavaScript 静默错误。其次,严格模式修复了使 JavaScript 引擎难以执行优化的错误:严格模式代码有时可以比非严格模式的相同代码运行得更快。第三,严格模式禁止某些可能在未来版本的 ECMAScript 中定义的语法。
严格模式是 ECMAScript 5 中的一项新功能,它允许开发人员将代码放入“严格”上下文中。这种严格的上下文有助于开发人员通过抛出更多异常来避免错误。
如何在js中使用严格模式?
简单的。把它扔在程序的顶部,为整个脚本启用它:
"use strict";
或者将它放在一个函数中,仅在该上下文中打开严格模式。
function imStrict(){
"use strict";
// … your code (executes in strict mode) …
}
在 JS 中使用严格模式的优点
1. 函数是块作用域内的块 作用域确定代码区域中变量或其他资源的可见性或可访问性
2. 如果变量被赋值但未定义任何类型,则引发错误/异常
在上面的示例中,“a”未声明任何值(let、const、var)
3. 如果在本地使用任何保留变量,则会引发错误 为将来的 JavaScript 版本保留的关键字不能用作严格模式下的变量名。
它们是: public implements interface let package private protected static yield 例如,
4. 简单函数中的“this”在严格模式下指向“undefined”。“this”关键字指的是调用函数的对象。 如果未指定对象,则严格模式下的函数将返回 undefined,普通模式下的函数将返回全局对象(窗口) 下面是示例以便更好地理解
默认情况下,类的主体以严格模式执行。例如:
class Rectangle {
//code executed here are in Strict mode
}
参考
问题:
以下是我遇到的问题。我正在关注一个教程,它最终尝试编译以下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
,它会顺利运行我的任务。
我很无奈,所以我一直用这个作为解决方案!但是在经历了其他一些 Stack Overflow Q&As 之后,我看到了以下答案:
sudo npm install -g n
sudo n stable
一旦我更新了我的 Node.js(到版本 10.x),然后通过作为终端运行以下命令来重建 Gulp,它就指示我:
npm rebuild node-sass --force
一切都好。所以就这样解决了。我已经撤消了对index.js
Gulp.js 模块文件所做的更改。现在它运行顺利。