JavaScript中使用“严格”做什么,背后的原因是什么?

时间:2009-08-26 16:10:14

标签: javascript syntax jslint use-strict

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

  

第1行问题1:缺少“使用严格”声明。

进行一些搜索,我意识到有些人将"use strict";添加到他们的JavaScript代码中。一旦我添加了语句,错误就会停止显示。不幸的是,谷歌没有透露这个字符串声明背后的历史。当然它必须与浏览器如何解释JavaScript有关,但我不知道效果会是什么。

那么"use strict";是什么,它意味着什么,它是否仍然相关?

当前任何浏览器是否都会响应"use strict";字符串,还是供将来使用?

31 个答案:

答案 0 :(得分:4691)

这篇关于Javascript Strict Mode的文章可能会让您感兴趣:John Resig - ECMAScript 5 Strict Mode, JSON, and More

引用一些有趣的部分:

  

严格模式是ECMAScript 5中的一项新功能,允许您在“严格”的操作环境中放置程序或函数。这种严格的上下文可以防止采取某些行动并引发更多例外。

  

严格模式有两种方式:

     
      
  • 它捕获了一些常见的编码器,抛出异常。
  •   
  • 当采取相对“不安全”的操作(例如获取对全局对象的访问权限)时,它会阻止或抛出错误。
  •   
  • 禁用令人困惑或思索不周的功能。
  •   

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

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 

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

所以,我认为它有点像你可以在Perl 中使用的"use strict"(因此名称?):通过检测更多可能导致的事情,它可以帮助您减少错误打破。

严格模式现在是supported by all major browsers。如果您在native ECMAScript modules(使用importexport语句)编写JavaScript,则始终启用严格模式,并且无法禁用。

答案 1 :(得分:1181)

这是ECMAScript 5的新功能.John Resig写了a nice summary

这只是一个放在JavaScript文件中的字符串(位于文件顶部或函数内部),如下所示:

"use strict";

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

答案 2 :(得分:597)

语句"use strict";指示浏览器使用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. 严格模式下的
  9. eval不会引入新变量

  10. 禁止删除普通名称(delete x;

  11. 禁止以任何形式绑定或分配名称evalarguments

  12. 严格模式不会使用形式参数别名arguments对象的属性。 (即在function sum (a,b) { return arguments[0] + b;}中这是有效的,因为arguments[0]绑定到a,依此类推。)

  13. arguments.callee不受支持

  14. [参考:Strict mode Mozilla开发者网络]

答案 3 :(得分:391)

如果人们担心使用use strict,可能值得查看这篇文章:

ECMAScript 5 'Strict mode' support in browsers. What does this mean?
   NovoGeek.com - Krishna的博客

它讨论了浏览器支持,但更重要的是如何安全地处理它:

function isStrictMode(){
    return !this;
} 
/*
   returns false, since 'this' refers to global object and 
   '!this' becomes false
*/

function isStrictMode(){   
    "use strict";
    return !this;
} 
/* 
   returns true, since in strict mode the keyword 'this'
   does not refer to global object, unlike traditional JS. 
   So here, 'this' is 'undefined' and '!this' becomes true.
*/

答案 4 :(得分:197)

请注意,所有为计算机付费的人:将"use strict"应用于现有代码可能会有危险!这个东西不是一些感觉良好,快乐的贴纸,你可以打上代码使其“更好”。使用"use strict"编译指示,浏览器会突然在以前从未扔过的随机位置中出现异常只是因为在那个位置你正在做一些默认/松散的JavaScript允许但是严格的JavaScript令人厌恶!您的代码中很少会使用严格违规隐藏,只会在最终运行时抛出异常 - 例如,在付费客户使用的生产环境中!

如果您想采取行动,最好将"use strict"与全面的单元测试和严格配置的JSHint构建任务一起应用,这将使您确信模块没有暗角因为你已经开启严格模式,这将会非常爆炸。或者,嘿,这是另一种选择:只是不要将"use strict"添加到任何遗留代码中,老实说,它可能更安全。 绝对不要"use strict"添加到您不拥有或维护的任何模块,例如第三方模块。

我认为尽管它是一种致命的笼养动物,"use strict"可能是好东西,但你必须做得对。严格要求的最佳时机是您的项目是绿地并且您从头开始。配置JSHint/JSLint时,所有警告和选项都会随着团队的需要而变得紧张,得到一个良好的构建/测试/断言系统,如同Grunt+Karma+Chai,并且只有那么开始标记所有新模块为"use strict"。准备好治愈许多琐碎的错误和警告。如果JSHint/JSLint产生任何违规行为,请确保每个人都了解重力,将构建配置为FAIL。

当我采用"use strict"时,我的项目不是一个绿地项目。结果,我的IDE充满了红色标记,因为我的一半模块上没有"use strict",并且JSHint抱怨这一点。这提醒我一下我将来应该做什么重构。我的目标是由于我所有遗失的"use strict"语句而被红色标记释放,但现在已经过去了几年。

答案 5 :(得分:150)

使用'use strict';并不会突然使您的代码更好。

JavaScript strict modeECMAScript 5中的一项功能。您可以通过在脚本/函数顶部声明这一点来启用严格模式。

'use strict';

当JavaScript引擎看到此指令时,它将开始以特殊模式解释代码。在这种模式下,当检测到可能最终成为潜在错误的某些编码实践时(这是严格模式背后的原因),会引发错误。

考虑这个例子:

var a = 365;
var b = 030;

在他们对数字文字排列的痴迷中,开发人员无意中用八进制文字初始化了变量b。非严格模式会将其解释为值为24的数字文字(在基数10中)。但是,严格模式会抛出错误。

有关严格模式的非专业清单,请参阅this answer

我应该在哪里使用'use strict';

  • 在我的 JavaScript应用程序中:绝对!当您使用代码做一些愚蠢的事情时,严格模式可以用作举报者。

  • 在我的现有 JavaScript代码中:可能不是!如果您现有的JavaScript代码包含严格模式下禁止的语句,则应用程序将会中断。如果您想要严格模式,您应该准备调试和更正现有代码。这就是使用'use strict';不会突然使您的代码更好的原因

如何使用严格模式?

  1. 在脚本之上插入'use strict';语句:

    // File: myscript.js
    
    'use strict';
    var a = 2;
    ....
    

    请注意,文件myscript.js中的所有内容都将以严格模式解释。

  2. 或者,在函数体上插入'use strict';语句:

    function doSomething() {
        'use strict';
        ...
    }
    

    函数doSomething词法范围中的所有内容都将以严格模式进行解释。 词汇范围这个词在这里很重要。有关更好的解释,请参阅this answer

  3. 在严格模式下禁止哪些事情?

    我发现nice article描述了严格模式下禁止的一些事情(请注意,这不是排他性列表):

      

    范围

         

    从历史上看,JavaScript一直困惑于功能如何   是范围的。有时他们似乎是静态范围的,但有些   功能使它们的行为类似于动态范围。这是   令人困惑,使程序难以阅读和理解。   误解会导致错误。这也是性能问题。   静态作用域允许在编译时发生变量绑定   时间,但动态范围的要求意味着绑定必须   延迟到运行时,它具有显着的性能   罚。

         

    严格模式要求静态完成所有变量绑定。   这意味着以前需要动态绑定的功能   必须被删除或修改。具体来说,with语句是   淘汰,以及评估功能的篡改能力   呼叫者的环境受到严格限制。

         

    严格代码的一个好处是像YUI Compressor这样的工具   在处理它时可以做得更好。

         

    隐含的全局变量

         

    JavaScript隐含了全局变量。如果   你没有显式声明一个变量,一个全局变量是   隐含地为你宣布。这使编程更容易   初学者,因为他们可以忽略一些基本的家务   家务。但它使更大程序的管理更多   困难,它显着降低了可靠性。严格来说   模式,不再创建隐含的全局变量。你应该   明确声明所有变量。

         

    全球泄漏

         

    有很多情况可能导致this   绑定到全局对象。例如,如果你忘了   在调用构造函数时提供new前缀   构造函数this将意外绑定到全局对象,所以   而不是初始化一个新对象,它将是静默的   篡改全局变量。在这些情况下,严格模式会   而是将this绑定到undefined,这将导致构造函数   抛出异常,允许检测错误   越快。

         

    嘈杂失败

         

    JavaScript一直都有只读属性,但是你   在ES5 Object.createProperty之前无法自己创建它们   功能暴露了这种能力。如果您尝试分配值   对于只读属性,它将无声地失败。任务将   不更改属性的值,但您的程序将继续执行   虽然它有。这是一种可导致程序的完整性危害   进入一个不一致的状态。在严格模式下,尝试更改   只读属性将抛出异常。

         

    八路

         

    数字的八进制(或基数8)表示极其重要   在使用word的机器上进行机器级编程时很有用   大小是3的倍数。在使用CDC时,您需要八进制   6600主机,字长为60位。如果你能读懂   八进制,你可以看一个单词为20位数。代表两位数   操作码,一位数字识别出8个寄存器中的一个。在此期间   从机器代码到高级语言的缓慢过渡,确实如此   被认为在编程语言中提供八进制表格很有用。

         

    在C中,一个非常不幸的八进制代表是   选中:领先零。所以在C中,0100表示64,而不是100,08表示   错误,而不是8.更不幸的是,这种时代错误已经存在   复制到几乎所有现代语言,包括JavaScript,在哪里   它仅用于创建错误。它没有其他目的。所以   严格模式,不再允许八进制形式。

         

    等等

         

    参数伪数组变得多一点   ES5中的数组类似。在严格模式下,它会丢失calleecaller   属性。这样就可以将arguments传递给不受信任的人   代码没有放弃很多保密的背景。而且,   功能的arguments属性被消除。

         

    在严格模式下,函数文字中的重复键将产生一个   语法错误。函数不能有两个具有相同名称的参数。   函数不能具有与其中一个名称相同的变量   参数。函数不能delete自己的变量。试图   delete一个不可配置的属性现在抛出一个异常。原始   值不会被隐式包装。

    未来JavaScript版本的保留字

    ECMAScript 5添加了一个保留字列表。如果将它们用作变量或参数,则严格模式将引发错误。保留字是:

      

    implementsinterfaceletpackageprivateprotectedpublicstaticyield

    进一步阅读

答案 6 :(得分:130)

我强烈建议每个开发人员立即开始使用严格模式。有足够的浏览器支持它,严格模式将合法地帮助我们避免我们甚至不知道你的代码中的错误。

显然,在初始阶段,我们以前从未遇到过错误。为了获得全部好处,我们需要在切换到严格模式后进行适当的测试,以确保我们已经捕获了所有内容。当然,我们不只是在代码中抛出use strict并假设没有错误。因此,流失是时候开始使用这个非常有用的语言功能来编写更好的代码。

例如,

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint是由Douglas Crockford编写的调试器。只需粘贴您的脚本,它就会快速扫描代码中的任何明显问题和错误。

答案 7 :(得分:91)

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

您可以参考MDN documentation了解更多信息。

"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 - 语句。
  • 在严格模式下,必须声明所有变量:如果为尚未声明为变量的标识符,函数,函数参数,catch-clause参数或全局Object的属性赋值,则你会得到一个ReferenceError。在正常模式下,标识符被隐式声明为全局变量(作为全局Object的属性)
  • 在严格模式下,关键字this在作为函数(而不是方法)调用的函数中具有值undefined。 (在正常模式下this始终指向全局Object)。这种差异可用于测试实现是否支持严格模式:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • 此外,当在严格模式下使用call()apply调用函数时,this正好是call()的第一个参数的值或apply()调用。 (在正常模式下,nullundefined将被全局Object替换,而非对象的值将被转换为对象。)

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

  • 在严格模式下,将代码传递给eval()时,您无法在调用者的范围内声明或定义变量或函数(正如您在普通模式下所做的那样)。相反,为eval()创建了一个新范围,变量和函数在该范围内。 eval()完成执行后,该范围将被销毁。
  • 在严格模式下,函数的arguments-object包含值的静态副本,这些副本将传递给该函数。在正常模式下,参数对象有一些神奇的" behavior:数组的元素和命名的函数参数都引用相同的值。
  • 在严格模式下,当SyntaxError运算符后跟非限定标识符(变量,函数或函数参数)时,您将获得delete。在正常模式下,delete表达式将不执行任何操作,并将其评估为false
  • 在严格模式下,当您尝试删除不可配置的属性时,您将获得TypeError。 (在正常模式下,尝试只是失败,delete表达式被评估为false)。
  • 在严格模式下,当您尝试为对象文字定义多个具有相同名称的属性时,会将其视为语法错误。 (在正常模式下没有错误。)
  • 在严格模式下,当函数声明具有多个具有相同名称的参数时,它被视为语法错误。 (在正常模式下没有错误。)
  • 在严格模式下,不允许八进制文字(这些是以0x开头的文字。(在正常模式下,某些实现允许八进制文字。)
  • 在严格模式下,标识符evalarguments被视为关键字。您不能更改它们的值,不能为它们赋值,也不能将它们用作变量,函数,函数参数或catch块标识符的名称。
  • 在严格模式下,对检查调用堆栈的可能性有更多限制。 arguments.callerarguments.callee在严格模式下导致函数TypeError。此外,当您尝试读取函数时,严格模式下函数的某些调用者和参数属性会导致TypeError

答案 8 :(得分:80)

我的两分钱:

严格模式的目标之一是允许更快地调试问题。它可以帮助开发人员在发生某些可能导致静默的错误事件时抛出异常。你网页的奇怪行为。我们使用use strict时,代码会抛出错误,这有助于开发人员提前修复它。

使用use strict后我学到的很少重要的事情:

阻止全局变量声明:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

现在,此代码在全局范围内创建nameoftree,可以使用window.nameoftree进行访问。当我们实现use strict时,代码会抛出错误。

  

未捕获的ReferenceError:未定义nameoftree

Sample

消除with声明:

with语句无法使用uglify-js等工具缩小。它们也是deprecated,已从未来的JavaScript版本中移除。

Sample

防止重复:

当我们有重复属性时,它会抛出异常

  

未捕获的SyntaxError:对象文字中的重复数据属性不是   允许在严格模式下

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

还有更多,但我需要获得更多的知识。

答案 9 :(得分:59)

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

命令周围的引号确保代码仍然可以在旧浏览器中工作(尽管在严格模式下生成语法错误的事情通常只会导致脚本在某些较难检测的方式中出现故障浏览器)。

答案 10 :(得分:55)

添加implements时,以下情况会在脚本执行之前抛出 SyntaxError

  • 为未来的ECMAScript版本铺平道路,使用其中一个新保留的关键字(预先设置 ECMAScript 6 ):interface,{ {1}},letpackageprivateprotectedpublicstaticyield

  • 在块中声明功能

    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(bug 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() { } 
    

来源:

答案 11 :(得分:51)

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

  • 通过更改它们来消除一些JavaScript无提示错误 抛出错误。

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

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

了解更多信息vistit Strict Mode- Javascript

答案 12 :(得分:49)

“使用严格”;是程序员不会使用JavaScript的松散或不良属性的保险。这是一个指南,就像一个统治者将帮助你做直线。 “使用严格”将帮助您进行“直接编码”。

那些不想使用统治者直接排队的人通常会在那些要求他人调试代码的页面中结束。

相信我。与设计不良的代码相比,开销可以忽略不计。 Doug Crockford, who has been a senior JavaScript developer for several years, has a very interesting post here。就个人而言,我喜欢一直回到他的网站,以确保我不忘记我的良好做法。

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

答案 13 :(得分:44)

从这一点开始,将use strict包含在所有敏感JavaScript文件的开头是一个很好的方法,可以成为更好的JavaScript程序员,避免随机变量变为全局变量,而且事情会发生变化。

答案 14 :(得分:38)

Quoting from w3schools

  

&#34;使用严格&#34;指令

     

&#34;使用严格&#34;指令是JavaScript 1.8.5中新增的(ECMAScript   版本5)。

     

它不是声明,而是前面忽略的文字表达   JavaScript版本。

     

&#34;使用严格&#34;的目的是表明代码应该是   在&#34;严格模式下执行&#34;。

     

使用严格模式时,您不能使用未声明的变量。

     

为何选择严格模式?

     

严格模式可以更轻松地编写&#34;安全&#34;的JavaScript。

     

先前接受的严格模式更改&#34;错误的语法&#34;变成真正的错误。

     

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

     

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

     

在严格模式下,对不可写属性的任何赋值,a   getter-only属性,不存在的属性,不存在的属性   变量或不存在的对象将引发错误。

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

答案 15 :(得分:33)

"use strict"使JavaScript代码在严格模式中运行,这基本上意味着在使用之前需要定义所有内容。使用严格模式的主要原因是为了避免未定义方法的意外全局使用。

同样在严格模式下,事情运行得更快,一些警告或无声警告会引发致命错误,最好总是使用它来制作更整洁的代码。

"use strict"广泛需要在ECMA5中使用,在ECMA6中默认情况下是JavaScript的一部分,因此如果您使用的是ES6,则无需添加。< / p>

请查看MDN的这些陈述和示例:

  

“使用严格”指令
“使用严格”指令是新的   JavaScript 1.8.5(ECMAScript版本5)。这不是陈述,而是陈述   文字表达式,被早期版本的JavaScript忽略。该   “use strict”的目的是表明代码应该是   以“严格模式”执行。使用严格模式,您不能,例如,   使用未声明的变量。

     

使用“严格使用”的例子:
  功能的严格模式:同样,为a调用严格模式   功能,把确切的声明“使用严格”; (或'使用严格';)in   在任何其他陈述之前,函数的主体。

1)功能严格模式

 function strict() {
     // Function-level strict mode syntax
     'use strict';
     function nested() { return 'And so am I!'; }
     return "Hi!  I'm a strict mode function!  " + nested();
 }
 function notStrict() { return "I'm not strict."; }

 console.log(strict(), notStrict());

2)全脚本严格模式

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3)分配给不可写的全局

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

你可以read more on MDN

答案 16 :(得分:29)

一些参与ECMAScript委员会的人有一个很好的谈话:Changes to JavaScript, Part 1: ECMAScript 5"关于"use strict"交换机的增量使用如何允许JavaScript实施者清理许多危险的功能JavaScript没有突然破坏世界上的每个网站。

当然,它还讨论了很多这些错误的内容以及ECMAScript 5如何修复它们。

答案 17 :(得分:18)

请注意,use strict中引入了public async Task<String> GetGoogleLocation(string address){ var request = new HttpRequestMessage(HttpMethod.Get, string.Format(GeoCodeApi, address)); var response = await this._proxy.SendAsync(request); return await response.Content.ReadAsStringAsync(); } ,此后一直保留。{/ p>

以下是在EcmaScript 5ES6中触发严格模式的条件:

  
      
  • 全局代码是严格模式代码,如果它以包含使用严格指令的指令序言开头(见14.1.1)。
  •   
  • 模块代码始终是严格的模式代码。
  •   
  • ClassDeclaration ClassExpression 的所有部分都是严格模式代码。
  •   
  • 如果Eval代码以包含Use Strict Directive的Directive Prologue开头,或者对eval的调用是严格模式代码中包含的直接eval(见12.3.4.1),则Eval代码是严格模式代码。
  •   
  • 如果关联的 FunctionDeclaration,FunctionExpression,GeneratorDeclaration,GeneratorExpression,MethodDefinition或ArrowFunction 包含在严格模式代码中,或者产生函数值[[]的代码,则函数代码是严格模式代码。 ECMAScriptCode]]内部插槽以指令序言开头,其中包含使用严格指令。
  •   
  • 作为内置函数和生成器构造函数的参数提供的函数代码是严格模式代码,如果最后一个参数是一个String,处理时是一个以指令序言开头的 FunctionBody 包含使用严格指令。
  •   

答案 18 :(得分:18)

要比较的小例子:

非严格模式:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

严格模式:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

非严格模式:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true

答案 19 :(得分:12)

开发人员使用"use strict"的主要原因是:

  1. 防止意外声明全局变量。使用"use strict()"将确保在使用前使用var声明变量。 例如:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
    
  2. N.B:"use strict"指令仅在脚本或函数的开头被识别。
  3. 字符串"arguments"不能用作变量:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. 将限制关键字用作变量。试图使用它们会引发错误。

  5. 简而言之,这将使您的代码不易出错,反过来会让您编写好的代码。

    要了解更多信息,请参阅here

答案 20 :(得分:11)

“使用严格”;是ECMA努力使JavaScript更加强大。它引入了JS,试图使其至少有一点“严格”(其他语言自90年代起实施严格的规则)。它实际上“迫使”JavaScript开发人员遵循某种编码最佳实践。 JavaScript仍然非常脆弱。没有类型变量,类型化方法等。 我强烈建议JavaScript开发人员学习更强大的语言,如Java或ActionScript3,并在JavaScript代码中实现相同的最佳实践,它将更好地工作并且更容易调试。

答案 21 :(得分:10)

UnhandledException += (sender, e) => { if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break(); }; 是一种让您的代码更安全的方法,因为您无法使用可能无法正常工作的危险功能。并且在使代码更严格之前进行了编写。

答案 22 :(得分:10)

在ECMAScript 5中引入了JavaScript“严格”模式。

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

在JS文件的最顶部写"use strict";会打开strict 语法检查。它为我们完成了以下任务:

    如果您尝试分配未声明的变量

    ,则
  1. 会显示错误

  2. 阻止您覆盖关键的JS系统库

  3. 禁止使用某些不安全或容易出错的语言功能

  4. use strict也适用于各个功能。在代码中包含use strict始终是一种更好的做法。

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

答案 23 :(得分:10)

使用Strict用于显示常见错误和重复错误,以便以不同方式处理错误,并更改java脚本运行的方式,这些更改包括:

  • 防止意外全局

  • 没有重复

  • 消除

  • 消除这种强制行为

  • 更安全的评估()

  • 不可变的错误

您还可以阅读此article了解详情

答案 24 :(得分:9)

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

如果使用"use strict",则应遵循严格的规则编写代码,从而减少错误和模糊的可能性。

答案 25 :(得分:2)

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

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

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

缺点

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

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

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

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

答案 26 :(得分:1)

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

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

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

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

答案 27 :(得分:1)

严格模式可消除在非严格模式下会被忽略的错误,从而使javascript“更加安全”。

是否考虑过最佳做法?

,在使用javascript纳入严格模式时,这被视为最佳做法的一部分。这是通过在您的JS文件中添加以下代码行来完成的。

'use strict';

在您的代码中。

对用户代理意味着什么?

指示应以严格模式解释代码,这会向浏览器之类的用户代理指定用户应按字面意义对待代码,如果代码不合理,则会抛出错误。

例如:考虑在您的.js文件中,您具有以下代码:

方案1:[无限制模式]

var city = "Chicago"
console.log(city) // Prints the city name, i.e. Chicago

方案2:[无限制模式]

city = "Chicago"
console.log(city) // Prints the city name, i.e. Chicago

那为什么在两种情况下都打印变量名?

在未启用严格模式的情况下,用户代理经常对有问题的代码进行一系列修改,以使代码有意义。从表面上看,这似乎是一件好事,而且确实,在严格模式下工作使人们可以在不弄清所有细节的情况下使用JavaScript代码。但是,作为开发人员,我不想在代码中留下错误,因为我知道它可能会回来并在以后咬住我,我也只想编写出色的代码。这就是严格模式可以提供帮助的地方。

方案3:[严格模式]

'use strict';

city = "Chicago"
console.log(city) // Reference Error: asignment is undeclared variable city.

其他提示: 要使用严格模式保持代码质量,则无需一遍又一遍地编写代码,尤其是当您有多个.js文件时。您可以在eslint规则中全局执行此规则,如下所示:

文件名: .eslintrc.js

module.exports = {
    env: {
        es6: true
    },
    rules : {
        strict: ['error', 'global'],
        },
    };
    

好吧,那么严格模式下可以防止什么?

  • 在未声明变量的情况下使用变量会在严格模式下引发错误。这是为了防止在整个应用程序中无意间创建全局变量。印刷芝加哥的示例特别涵盖了这一点。

  • 在严格模式下删除变量,函数或参数是不可以的。

    "use strict";
     function x(p1, p2) {}; 
     delete x; // This will cause an error
    
  • 在严格模式下不允许复制参数名称

     "use strict";
     function x(p1, p1) {};   // This will cause an error
    
  • 在严格模式下,不允许使用Javascript语言保留字。这些词是工具接口,让,包,私有,受保护,公开。静态和收益

有关更全面的列表,请查看MDN文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

答案 28 :(得分:0)

由于浏览器战争和糟糕的管理,JavaScript 的设计和实现很仓促。结果,许多糟糕的设计决策、不直观的语法和令人困惑的语义进入了语言。严格模式旨在修正其中一些错误。

但是在不创建替代解释的情况下修复这些错误会破坏向后兼容性。因此,pytkdocs 指令在将代码传达给程序员的同时创建了该代码的替代解释。

例如,"use strict" 关键字指的是方法定义中的对象,如其他语言中的 thisthis

self

let o = { name: 'John Doe', sayName: function(){ console.log(this.name); } }; o.sayName(); // 'John Doe' 在方法上下文之外没有任何用途,但所有 JavaScript 函数都有 this 关键字,无论它们是否是方法:

this

此处的 function run() { console.log(this); } run(); // Window 解析为没有意义且没有任何用途的全局对象,因为全局对象已在作用域中可用。

在严格模式下,全局函数中的 this 解析为 undefined,这正是我们所期望的。

this

有些错误即使在严格模式下也无法修复,因为语法应该对旧浏览器有效,因为它们忽略 "use strict" function run() { console.log(this); } run(); // undefined 指令。这是设计使然。

答案 29 :(得分:0)

我应该在 NodeJs 中使用严格模式吗?

默认的 NodeJS 设置,当您首先使用 npm init 命令初始化项目时,不使用严格模式。

<块引用>

NodeJS 默认使用 CommonJS 模块化。

如果您对此感到满意,则无需使用它。 但是

您可能已经在考虑它可以在服务器端提供什么好处。


非严格模式示例:

假设我们有一个包含以下设置的 app.js 文件(我以这种方式导入模块以强调不同的模式)

//app.js
const nonStrictMode = require('./non-strict');
nonStrict.myFunc();

// non-strict.js
module.exports = {
    myFunc: () => {
        console.log('Non strict mode.');
        const fixed = {};
        Object.preventExtensions(fixed);
        fixed.newProperty = 'newProp';
        console.log(fixed.newProperty);
        console.log('Non strict mode finished.');
    }
};

它是非严格模式下完整有效的 JavaScript 语法。但它不会像您期望的那样工作。并且您不会收到编译时错误。

输出将是:

Non strict mode.
*undefined*
Non strict mode finished

这不是你想要的,对吧?所以如果能抛出一个错误来通知你这个“问题”会更好。


严格模式示例:

// app.js
const strictMode = require('./strict');
strictMode.myFunc();

// strict.js
'use strict';

module.exports = {
    myFunc: () => {
        console.log('Strict mode on.');
        const fixed = {};
        Object.preventExtensions(fixed);
        fixed.newProperty = 'newProp';
        console.log('Strict mode finished.');
    }
};

输出将是:

Strict mode on.
TypeError: Cannot add property newProperty, object is not extensible.

那么,是不是不能给冻结的对象添加属性?

不,它不是,而且得到一个编译时错误比完全避免这个错误要好得多。

如你所见,我使用了'use strict';在这个 .js 文件的顶部。所以也许你最好也使用这个配置。


或 .. 或者,另一个例子:

// This will also become a global variable as global functions have
// global `this` as the contextual `this` in non strict mode
function hello() {
    foo = "Message";
}

当你给一个未声明的变量赋值时,JavaScript 会自动将它提升为默认模式下的全局变量。在这里,memory leaks 问题开始了。

为了避免这种意外,请始终使用“use strict”在严格模式下编写 JavaScript; JS 文件顶部的注释。在严格模式下,上述会导致错误。


我希望我说清楚了。

也可以在 Nodejs 中使用它

答案 30 :(得分:-2)

"use strict" 让 JavaScript 处于“严格模式”,因此 JavaScript 变得更严格。 在严格模式下,我们不能使用关键字作为变量名。

"use strict";
var arguments = "value"; //This will generate an error
var static = "value 2"; //This will also generate an error

在严格模式下,我们不能使用未初始化的变量。

"use strict";
myVar = 0; //This will generate an error.
counter = 9;//This will generate an error too.
counter++; 

我们不能在严格模式下删除函数或变量。

"use strict";
function myFunc() {
 return true;
}
delete myFunc; //This will generate an error
var myVar = 0;
delete myVar; //This will generate an error too.

最好在严格模式下编码以减少错误,并编写更好的代码。