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

时间:2011-12-28 03:04:59

标签: javascript strict-mode

我一直在浏览Mozilla开发者网络上的JavaScript参考,我发现了一个名为"strict mode"的东西。我读了它,我很难理解它的作用。有人可以简要解释(一般)它的目的是什么以及它有用吗?

8 个答案:

答案 0 :(得分:147)

其主要目的是进行更多检查。

只需在代码顶部添加"use strict";,然后再添加其他内容。

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

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

大部分时间你并不是要在某个任意范围的中间创建全局变量,因此大多数时候写blah = 33是一个错误,程序员实际上并不希望它成为一个全局变量,他们打算写var blah = 33

它同样不允许许多在技术上有效的事情。 NaN = "lol"不会产生错误。它也不会改变NaN的值。 using strict(和类似的奇怪语句)会产生错误。大多数人都很欣赏这一点,因为没有理由写NaN = "lol",所以最有可能是拼写错误。

Read more at the MDN page on strict mode

答案 1 :(得分:33)

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属性。

答案 2 :(得分:21)

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

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

  

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

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

  

SES(安全ECMAScript)设计实验

     

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

     

应该有从SES到ES5 / Strict的直接翻译。

标准的

Annex C解释了严格模式和普通模式之间的差异。

  

严格模式限制和例外

     
      
  • 标识符"实现"," 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)操作的UnaryExpression。 5)运营商。   严格模式函数的参数对象定义名为" caller"的非配置访问器属性。和"被叫"在访问时抛出TypeError异常(10.6)。
  •   
  • 严格模式函数的参数对象不会使用其函数的相应形式参数绑定动态共享其数组索引属性值。 (10.6)。   对于严格模式函数,如果创建了一个arguments对象,则本地标识符参数与arguments对象的绑定是不可变的,因此可能不是赋值表达式的目标。 (10.5)。
  •   
  • 如果严格模式代码包含具有多个任何数据属性定义的ObjectLiteral(11.1.5),则为SyntaxError。   如果标识符" eval"它是一个SyntaxError。或标识符"参数"作为PropertyAssignment的PropertySetParameterList中的标识符出现,该标识包含在严格的代码中或者其FunctionBody是严格的代码(11.1.5)。
  •   
  • 严格模式评估代码无法在调用者的变量环境中将变量或函数实例化为eval。而是创建一个新的变量环境,该环境用于eval代码的声明绑定实例化(10.4.2)。
  •   
  • 如果在严格模式代码中对此进行评估,则不会将此值强制转换为对象。此null或undefined值不会转换为全局对象,并且原始值不会转换为包装器对象。通过函数调用传递的此值(包括使用Function.prototype.apply和Function.prototype.call进行的调用)不会强制将此值传递给对象(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出现在严格代码中且其Identifier是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)。
  •   
  • 在严格模式代码中使用的是SyntaxError,标识符eval或arguments作为FunctionDeclaration或FunctionExpression的标识符或作为形式参数名称(13.1)。尝试使用Function构造函数(15.3.2)动态定义此类严格模式函数将引发SyntaxError异常。
  •   

答案 3 :(得分:6)

  

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

在代码中调用严格模式

严格模式适用于整个脚本或单个功能。它不适用于{}括号中的块语句,尝试将其应用于此类上下文时无效。

整个脚本:

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

// 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无声错误。

For Instance:使用严格模式的代码

enter image description here

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

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

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

// Will not throw an error

使用严格模式的优势:

  • 通过抛出错误来消除JavaScript无提示错误。
  • 修复了使JavaScript引擎难以执行优化的错误。
  • 使代码运行速度更快,而不是严格模式下的相同代码
  • 禁止在ECMAScript的未来版本中定义某些语法。

答案 4 :(得分:5)

严格模式对普通JavaScript语义进行了一些更改。

  • 严格模式通过将其更改为抛出错误来消除一些JavaScript无提示错误。

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

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

答案 5 :(得分:1)

ECMAScript5介绍了一些新的对象和属性,以及所谓的"strict mode"

严格模式是排除弃用功能的语言的子集。严格的 模式是选择加入而不是必需的,这意味着如果您希望您的代码在中运行 严格模式,你声明你的意图使用(每个功能一次,或一次 整个程序)以下字符串:

"use strict";

答案 6 :(得分:1)

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

  

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


  

严格模式对普通JavaScript语义进行了一些更改。   首先,严格模式消除了一些JavaScript无声错误   改变它们以抛出错误。其次,严格模式修复了错误   使JavaScript引擎难以执行优化:   有时可以使严格模式代码运行得比完全相同   代码不是严格的模式。第三,严格模式禁止一些语法   可能会在ECMAScript的未来版本中定义。

答案 7 :(得分:0)

<强>问题:
以下是我遇到的问题,我正在按照教程进行操作,最后尝试编译以下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...

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

我很无奈,所以我继续使用它作为解决方案!但是经过一些其他的SO Q&A's I saw following answer后如下:

sudo npm install -g n
sudo n stable

我越早更新我的NodeJ(到版本10.x),然后在终端指示我的情况下运行以下命令重建Gulp:

npm rebuild node-sass --force

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

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