8124

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

第 1 行字符 1 的问题:缺少“use strict”语句。

做了一些搜索,我意识到有些人添加"use strict";到他们的 JavaScript 代码中。一旦我添加了语句,错误就停止出现了。不幸的是,谷歌没有透露这个字符串声明背后的大部分历史。当然,这一定与浏览器如何解释 JavaScript 有关,但我不知道会产生什么影响。

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

当前的浏览器是否响应该"use strict";字符串或是否供将来使用?

4

29 回答 29

5293

ES6 模块更新

原生 ECMAScript 模块(withimportexport语句)和ES6 类中,严格模式始终处于启用状态且无法禁用。

原始答案

您可能会对这篇关于 Javascript 严格模式的文章感兴趣:John Resig - ECMAScript 5 严格模式、JSON 等

引用一些有趣的部分:

严格模式是 ECMAScript 5 中的一项新功能,它允许您将程序或函数置于“严格”操作上下文中。这种严格的上下文会阻止执行某些操作并引发更多异常。

和:

严格模式有几个方面的帮助:

  • 它捕获一些常见的编码错误,抛出异常。
  • 当采取相对“不安全”的操作(例如获得对全局对象的访问权)时,它可以防止或引发错误。
  • 它禁用了令人困惑或考虑不周的功能。

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

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code...

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

所以,我想它有点像"use strict"你可以在 Perl 中使用的(因此得名?):它通过检测更多可能导致损坏的东西来帮助你减少错误。

现在所有主要浏览器都支持严格模式。

于 2009-08-26T16:15:39.370 回答
1364

这是 ECMAScript 5 的一个新特性。John Resig 写了一个很好的总结

它只是您放入 JavaScript 文件(文件顶部或函数内部)的字符串,如下所示:

"use strict";

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

于 2009-08-26T16:14:23.880 回答
773

该语句"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. eval在严格模式下不引入新变量

  9. 禁止删除纯名称 ( delete x;)

  10. 禁止以任何形式绑定eval或分配名称arguments

  11. 严格模式不arguments使用形式参数对对象的属性进行别名。(例如在function sum (a,b) { return arguments[0] + b;}This works because arguments[0]is bound toa等。)

  12. arguments.callee不支持

[参考:严格模式Mozilla 开发者网络]

于 2014-11-24T21:22:08.303 回答
458

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

浏览器中的 ECMAScript 5“严格模式”支持。这是什么意思?
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.
*/
于 2012-07-15T23:25:53.957 回答
243

提醒一句,你们这些强硬的程序员:应用于"use strict"现有代码可能是危险的!这东西不是你可以在代码上贴上“更好”的感觉良好、快乐的表情贴纸。使用"use strict"编译指示,浏览器会突然在它之前从未抛出的随机位置抛出异常,因为在那个位置你正在做一些默认/松散的 JavaScript 愉快地允许但严格的 JavaScript 厌恶的事情!您可能在代码中很少使用的调用中隐藏了严格性违规,这些调用只会在它们最终运行时抛出异常 - 例如,在您的付费客户使用的生产环境中!

如果您打算冒险,最好"use strict"与全面的单元测试和严格配置的 JSHint 构建任务一起应用,这将使您有信心,您的模块没有黑暗的角落会因为您而可怕地爆炸'已开启严格模式。或者,嘿,这是另一种选择:只是不要添加"use strict"到您的任何遗留代码中,老实说,这样可能更安全。 绝对不要添加"use strict"到您不拥有或维护的任何模块,例如第三方模块。

我认为即使它是一种致命的笼中动物,"use strict"也可以是好东西,但你必须做对。严格要求的最佳时机是当您的项目处于未开发阶段并且您从头开始时。将所有警告和选项配置JSHint/JSLint得尽可能严格,获得一个好的构建/测试/断言系统 du jour rigged like Grunt+Karma+Chai,然后才开始将所有新模块标记为"use strict". 准备好解决许多琐碎的错误和警告。JSHint/JSLint如果产生任何违规行为,通过将构建配置为 FAIL 来确保每个人都了解严重性。

当我采用"use strict". 结果,我的 IDE 充满了红色标记,因为我没有"use strict"一半的模块,而 JSHint 对此抱怨。这提醒了我将来应该做什么重构。我的目标是因为我所有的遗漏"use strict"陈述而没有红色标记,但那是几年后的事了。

于 2014-03-03T07:37:19.963 回答
226

使用'use strict';不会突然让你的代码变得更好。

JavaScript 严格模式ECMAScript 5中的一个特性。您可以通过在脚本/函数的顶部声明它来启用严格模式。

'use strict';

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

考虑这个例子:

var a = 365;
var b = 030;

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

有关严格模式下的非详尽专业列表,请参阅此答案


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

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

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


如何使用严格模式?

  1. 'use strict';在脚本顶部插入一条语句:

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

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

  2. 'use strict';或者,在函数体顶部插入一条语句:

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

    函数词法范围内的所有内容都doSomething将在严格模式下解释。词法作用域这个词在这里很重要。例如,如果您的strict代码调用了非 strict库的函数,则只有您的代码在严格模式下执行,而不是被调用的函数。请参阅此答案以获得更好的解释。


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

我找到了一篇很好的文章,描述了严格模式下禁止的几件事(请注意,这不是一个详尽的列表):

范围

从历史上看,JavaScript 一直对函数的作用域感到困惑。有时它们似乎是静态作用域的,但某些特性使它们表现得像动态作用域一样。这是令人困惑的,使程序难以阅读和理解。误解会导致错误。这也是性能的问题。静态作用域允许变量绑定在编译时发生,但动态作用域的要求意味着绑定必须推迟到运行时,这会带来显着的性能损失。

严格模式要求所有变量绑定都是静态完成的。这意味着必须消除或修改以前需要动态绑定的功能。具体来说,取消了 with 语句,并且 eval 函数篡改其调用者环境的能力受到严格限制。

严格代码的好处之一是YUI Compressor之类的工具 在处理它时可以做得更好。

隐含的全局变量

JavaScript 有隐含的全局变量。如果您没有显式声明变量,则会为您隐式声明一个全局变量。这使初学者更容易编程,因为他们可以忽略一些基本的家务活。但它使大型程序的管理变得更加困难,并且大大降低了可靠性。所以在严格模式下,不再创建隐含的全局变量。您应该显式声明所有变量。

全球泄漏

有许多情况可能导致this 绑定到全局对象。例如,如果您new在调用构造函数时忘记提供前缀,则构造函数this将意外绑定到全局对象,因此它不会初始化新对象,而是会默默地篡改全局变量。在这些情况下,严格模式将改为绑定thisundefined,这将导致构造函数改为抛出异常,从而可以更快地检测到错误。

嘈杂的失败

JavaScript 一直都有只读属性,但在 ES5 的Object.createProperty 函数公开该功能之前,您无法自己创建它们。如果您尝试将值分配给只读属性,它将静默失败。赋值不会改变属性的值,但你的程序会继续进行,就好像它已经改变了一样。这是一种完整性风险,可能导致程序进入不一致的状态。在严格模式下,尝试更改只读属性将引发异常。

八进制

在字长为 3 的倍数的机器上进行机器级编程时,数字的八进制(或以 8 为基数)表示非常有用。在使用字长为 60 位的 CDC 6600 大型机时需要八进制。如果您可以阅读八进制,您可以将一个单词视为 20 位数字。两位代表操作码,一位代表 8 个寄存器之一。在从机器代码缓慢过渡到高级语言的过程中,人们认为在编程语言中提供八进制形式是有用的。

在 C 中,选择了一个非常不幸的八进制表示:前导零。所以在 C 中,0100表示 64,而不是 100,并且08是错误,而不是 8。更不幸的是,这种不合时宜的现象已被复制到几乎所有现代语言中,包括 JavaScript,它仅用于创建错误。它没有其他目的。所以在严格模式下,八进制形式不再被允许。

等等

arguments 伪数组在 ES5 中变得更像数组了。在严格模式下,它会失去其calleecaller 属性。这使得您可以在arguments不放弃大量机密上下文的情况下将您的代码传递给不受信任的代码。此外, arguments还消除了函数的属性。

在严格模式下,函数字面量中的重复键会产生语法错误。一个函数不能有两个同名的参数。函数不能有与其参数之一同名的变量。函数不能delete拥有自己的变量。对不可配置属性的尝试 delete现在会引发异常。原始值不是隐式包装的。


未来 JavaScript 版本的保留字

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

implements, interface, let, package, private, protected, public, static, 和yield


延伸阅读

于 2016-01-29T11:35:48.273 回答
154

我强烈建议每个开发者现在就开始使用严格模式。有足够多的浏览器支持它,严格模式将合法地帮助我们避免我们甚至不知道您的代码中存在的错误。

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

例如,

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

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

于 2013-07-05T19:38:24.830 回答
109

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

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

"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. 在正常模式下,标识符被隐式声明为全局变量(作为 global 的属性Object
  • 在严格模式下,关键字在作为函数(而不是方法)调用的函数中this具有值。undefined(在正常模式下this总是指向全局Object)。这种差异可用于测试实现是否支持严格模式:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • 同样,当以严格模式调用call()或调用函数时,则恰好是or调用的第一个参数的值。(在正常模式下,被全局替换,并且不是对象的值被转换为对象。)applythiscall()apply()nullundefinedObject

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

  • 在严格模式下,将代码传递给 时eval(),您不能在调用者的范围内声明或定义变量或函数(就像在普通模式下一样)。相反,会为其创建一个新范围,eval()并且变量和函数都在该范围内。该范围在eval()完成执行后被销毁。
  • 在严格模式下,函数的 arguments-object 包含传递给该函数的值的静态副本。在正常模式下,arguments-object 具有某种“神奇”的行为:数组的元素和命名的函数参数都引用相同的值。
  • 在严格模式下,SyntaxErrordelete运算符后跟非限定标识符(变量、函数或函数参数)时,您将得到 a。在正常模式下,delete表达式什么都不做,并被评估为false.
  • TypeError在严格模式下,当您尝试删除不可配置的属性时,您会得到一个。(在正常模式下,尝试简单地失败并且delete表达式被评估为false)。
  • 在严格模式下,当您尝试为对象字面量定义多个具有相同名称的属性时,它会被视为语法错误。(在正常模式下没有错误。)
  • 在严格模式下,当函数声明具有多个同名参数时,它被认为是语法错误。(在正常模式下没有错误。)
  • 在严格模式下,不允许使用八进制文字(这些是以 . 开头的文字0x。(在正常模式下,某些实现确实允许使用八进制文字。)
  • 在严格模式下,标识符evalarguments被视为关键字。你不能改变它们的值,不能给它们赋值,你不能将它们用作变量、函数、函数参数或catch块的标识符的名称。
  • 在严格模式下,对检查调用堆栈的可能性有更多限制。arguments.callerarguments.callee导致 aTypeError在严格模式下的函数中。TypeError此外,当您尝试读取它们时,严格模式下函数的某些调用者和参数属性会导致 a 。
于 2015-05-15T06:58:03.453 回答
94

我的两分钱:

严格模式的目标之一是允许更快地调试问题。当发生某些可能导致网页无声和奇怪行为的错误事件时,它会通过抛出异常来帮助开发人员。在我们使用的那一刻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之类的工具来缩小语句。它们也已被弃用并从未来的 JavaScript 版本中删除。

Sample

防止重复:

当我们有重复的属性时,它会引发异常

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

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

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

于 2014-10-21T13:31:24.747 回答
71

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

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

于 2012-03-10T03:31:15.407 回答
66

添加"use strict";时,以下情况会在脚本执行前抛出SyntaxError :

  • 为未来的 ECMAScript 版本铺平道路,使用新保留的关键字之一(在ECMAScript 6之前):implements, interface, let, package, private, protected, public,staticyield.

  • 在块中声明函数

    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 不再是这种情况(错误 1041128)。

  • 用同名函数声明两个函数参数

    f(a, b, b){}
    
  • 将值设置为未声明的变量

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • delete在变量名上使用delete myVariable;

  • 使用evalorarguments作为变量或函数参数名称

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 
    

资料来源:

于 2015-12-23T03:10:38.823 回答
61

“使用严格”;是程序员不会使用 JavaScript 松散或坏的属性的一种保险。它是一个指南,就像尺子会帮助你画直线一样。“使用严格”将帮助您进行“直接编码”。

那些不喜欢使用标尺来直线直线的人通常会在那些页面中要求其他人调试他们的代码。

相信我。与设计不佳的代码相比,开销可以忽略不计。Doug Crockford 已经担任了几年的高级 JavaScript 开发人员,在这里有一篇非常有趣的帖子。就个人而言,我喜欢一直回到他的网站,以确保我不会忘记我的好习惯。

现代 JavaScript 实践应该总是唤起“使用严格”;语用。ECMA Group 将“严格”模式设为可选的唯一原因是允许经验不足的编码人员访问 JavaScript,并给他们时间适应新的和更安全的编码实践。

于 2013-05-31T18:29:33.943 回答
61

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

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

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

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

有关更多信息,请访问严格模式 - Javascript

于 2014-03-27T12:18:30.063 回答
55

use strict从这一点开始,在所有敏感的 JavaScript 文件的开头包含一个小方法是成为一个更好的 JavaScript 程序员并避免随机变量成为全局变量并且事情无声无息地变化。

于 2014-09-05T12:53:26.697 回答
47

引用 w3schools

“使用严格”指令

“use strict”指令是 JavaScript 1.8.5(ECMAScript 版本 5)中的新指令。

它不是语句,而是文字表达式,被早期版本的 JavaScript 忽略。

“使用严格”的目的是表明代码应该以“严格模式”执行。

例如,在严格模式下,您不能使用未声明的变量。

为什么是严格模式?

严格模式使编写“安全”JavaScript 变得更容易。

严格模式将以前接受的“错误语法”更改为真正的错误。

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

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

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

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

于 2015-04-29T10:10:19.480 回答
41

"use strict"使 JavaScript 代码在严格模式下运行,这基本上意味着一切都需要在使用前定义。使用严格模式的主要原因是避免意外全局使用未定义的方法。

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

"use strict"广泛需要在 ECMA5 中使用,在 ECMA6 中它默认是 JavaScript 的一部分,因此如果您使用的是 ES6,则不需要添加它。

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

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

使用“use strict”的例子:
函数的严格模式:同样,要为函数调用严格模式,请输入确切的语句“use strict”;(或'use strict';)在任何其他语句之前的函数体中。

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

您可以在 MDN 上阅读更多内容

于 2017-05-22T12:38:35.987 回答
33

ECMAScript 委员会的一些人发表了一篇精彩的演讲:JavaScript 的变化,第 1 部分:ECMAScript 5”关于如何增量使用"use strict"开关允许 JavaScript 实现者在不突然破坏每个网站的情况下清理 JavaScript 的许多危险特性在世界上。

当然,它还谈到了这些错误功能中的很多(曾经)以及 ECMAScript 5 如何修复它们。

于 2014-03-29T00:47:24.887 回答
29

比较的小例子:

非严格模式:

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

于 2016-08-21T21:43:24.477 回答
21

请注意,这use strict是在EcmaScript 5中引入并从那时起保留的。

以下是在ES6ES7中触发严格模式的条件:

  • 如果全局代码以包含使用严格指令的指令序言开头(参见 14.1.1),则它是严格模式代码。
  • 模块代码始终是严格模式代码。
  • ClassDeclarationClassExpression的所有部分都是严格模式代码。
  • 如果 Eval 代码以包含 Use Strict 指令的 Directive Prologue 开头,或者如果对 eval 的调用是包含在严格模式代码中的直接 eval(参见 12.3.4.1),则它是严格模式代码。
  • 如果相关的FunctionDeclaration、FunctionExpression、GeneratorDeclaration、GeneratorExpression、MethodDefinition 或 ArrowFunction包含在严格模式代码中,或者如果生成函数 [[ECMAScriptCode]] 内部槽值的代码以指令序言开头,则函数代码是严格模式代码包含使用严格指令。
  • 如果最后一个参数是一个字符串,作为参数提供给内置函数和生成器构造函数的函数代码是一个严格模式代码,该字符串在处理时是一个以包含使用严格指令的指令序言开头的FunctionBody 。
于 2016-04-12T00:25:07.760 回答
15

开发人员应该使用的主要原因"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. 注意:该"use strict"指令仅在脚本或函数的开头被识别。
  3. 字符串"arguments"不能用作变量:

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

简而言之,这将使您的代码不易出错,进而使您编写出好的代码。

要了解更多信息,您可以参考此处

于 2016-11-18T09:53:55.237 回答
14

use strict是一种使您的代码更安全的方法,因为您不能使用无法按预期工作的危险功能。而且,如前所述,它使代码更加严格。

于 2016-05-17T22:31:29.230 回答
13

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

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

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

  1. 如果您尝试分配给未声明的变量,则会显示错误

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

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

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

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

于 2016-11-11T05:40:45.873 回答
12

通常,JavaScript 不遵循严格的规则,因此增加了出错的机会。在使用之后"use strict",JavaScript 代码应遵循与其他编程语言一样的严格规则集,例如终止符的使用、初始化前的声明等。

如果"use strict"使用,则应遵循一组严格的规则编写代码,从而减少错误和歧义的机会。

于 2016-11-20T16:23:54.853 回答
12

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

于 2016-05-03T12:59:03.853 回答
11

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

  • 防止意外的全局变量

  • 没有重复

  • 消除与

  • 消除这种强制

  • 更安全的 eval()

  • 不可变的错误

你也可以阅读这篇文章了解详情

于 2016-10-17T13:59:15.043 回答
7

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

  • “use strict”指令是 ECMAScript 版本 5 中的新指令。
  • 它不是语句,而是文字表达式,被早期版本的 JavaScript 忽略。
  • “使用严格”的目的是表明代码应该以“严格模式”执行。
  • 例如,在严格模式下,您不能使用未声明的变量。

所有现代浏览器都支持“使用严格”,除了Internet Explorer 9 和更低版本

坏处

如果开发人员使用了严格模式下的库,但开发人员习惯于在正常模式下工作,他们可能会在库上调用一些无法按预期工作的操作。

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

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

人们通常认为你一开始就不应该使用这些东西,但是一些开发人员不喜欢这种约束并且想要使用该语言的所有特性。

于 2019-01-28T10:42:25.557 回答
4

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

请检查以下以非严格模式编写的函数:

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

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

于 2019-07-08T08:46:51.390 回答
4

由于浏览器大战和管理不善,JavaScript 被匆忙设计和实施。结果,许多糟糕的设计决策、不直观的语法和混乱的语义都进入了语言。严格模式旨在修正其中一些错误。

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

例如,this关键字是指方法定义中的对象,例如thisself其他语言。

let o = {
  name: 'John Doe',
  sayName: function(){
    console.log(this.name);
  }
};

o.sayName(); // 'John Doe'

this在方法上下文之外没有任何用途,但所有 JavaScript 函数都有this关键字,无论它们是否是方法:

function run() {
  console.log(this);
}

run(); // Window

这里this解析为没有意义且没有任何用途的全局对象,因为全局对象已经在范围内可用。

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

"use strict"

function run() {
  console.log(this);
}

run(); // undefined

即使在严格模式下也无法修复一些错误,因为语法对于旧浏览器应该是有效的,因为它们忽略了"strict mode"指令。这是设计使然。

于 2021-07-25T07:14:24.373 回答
4

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

它是否被视为最佳实践?

的,在使用 javascript 以包含Strict mode时,它​​被认为是最佳实践的一部分。这是通过在您的 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 语言中的保留字不允许在严格模式下使用。这些词是implements interface、let、packages、private、protected、public。静态和产量

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

于 2020-07-10T07:21:29.110 回答