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

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

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

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

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

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

1191789 次浏览

这是ECMAScript 5的一个新特性。John Resig编写了其中的一个不错的总结

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

"use strict";

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

ES6模块更新

原生ECMAScript模块(使用#0#1语句)和es6类中,始终启用严格模式,不能禁用。

原答复

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

引用一些有趣的部分:

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

还有:

严格模式有助于在几个方面:

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

另请注意,您可以将“严格模式”应用于整个文件……或者您可以仅将其用于特定函数(引用John Resig的文章)

// Non-strict code...
(function(){"use strict";
// Define your library strictly...})();
// Non-strict code...

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

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

严格模式现在是支持所有主流浏览器

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

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

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

浏览器中的ECMAScript 5“严格模式”支持。这意味着什么?
NovoGeek.com-克里希纳的博客

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

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

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

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

相信我。与设计不佳的代码相比,开销可以忽略不计。Doug Crockford,多年来一直是高级JavaScript开发人员,在这里有一篇非常有趣的文章。就我个人而言,我喜欢一直回到他的网站,以确保我不会忘记我的良好实践。

现代JavaScript实践应该总是唤起“使用严格”;Pragma。 ECMA集团选择“严格”模式的唯一原因是允许经验不足的程序员访问JavaScript,并给他们时间来适应新的和更安全的编码实践。

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

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

例如,

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

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

提醒一句,所有要求严格的程序员:将"use strict"应用于现有代码可能是危险的!这件事不是你可以在代码上贴一些感觉良好,快乐的贴纸来让它变得“更好”。使用"use strict"规则,浏览器会突然在它以前从未抛出的随机位置抛出异常,只是因为在那个地方你正在做一些默认/松散的JavaScript愉快地允许但严格的JavaScript厌恶的事情!你的代码中很少使用的调用中可能隐藏着严格的违规行为,只有当它们最终运行时才会抛出异常-比如说,在你付费客户使用的正式生产环境中!

如果你打算冒险尝试一下,最好在全面的单元测试和严格配置的JSHint构建任务的同时应用"use strict",这将给你一些信心,让你相信你的模块没有黑暗的角落会因为你打开了严格模式而爆炸。或者,嘿,这是另一个选择:不要将"use strict"添加到你的任何遗留代码中,老实说,这样可能更安全。绝对不可以"use strict"添加到任何你不拥有或维护的模块,比如第三方模块。

我认为即使它是一个致命的笼中动物,"use strict"也可以是好东西,但你必须做得对。严格要求的最佳时机是当你的项目是全新的,你从头开始。配置JSHint/JSLint,所有警告和选项尽可能紧地启动,像Grunt+Karma+Chai一样安装一个好的构建/测试/断言系统,然后开始将你所有的新模块标记为"use strict"。准备好纠正许多琐碎的错误和警告。如果JSHint/JSLint产生任何违规行为,通过将构建配置为FAIL来确保每个人都理解重力。

当我采用"use strict"时,我的项目还不是一个绿地项目。结果,我的IDE充满了红标,因为我一半的模块上没有"use strict",JSHint为此抱怨。这提醒我未来应该做什么重构。我的目标是因为我所有缺少"use strict"语句而没有红标,但那是几年后的事了。

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

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

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

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

了解更多信息vistit严格模式-Javascript

ECMAScript委员会的一些人有一个很好的演讲:对JavaScript的更改,第1部分:ECMAScript 5”关于"use strict"开关的增量使用如何允许JavaScript实现者清理JavaScript的许多危险功能,而不会突然破坏世界上的每个网站。

当然,它也讨论了很多这些错误功能是什么,以及ECMAScript 5如何修复它们。

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

我的两分钱:

严格模式的目标之一是允许更快地调试问题。当某些错误发生时,它通过抛出异常来帮助开发人员,这些错误可能导致您的网页出现无声和奇怪的行为。当我们使用 use strict时,代码将抛出错误,帮助开发人员提前修复它。

使用 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时,代码会抛出错误。

未捕获的引用错误:nameoftree未定义

删除with语句:

with语句不能使用像uglify-js相关文档这样的工具来缩小。它们也是已弃用,并从未来的JavaScript版本中删除。

样本:

"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;
for (var i = 0; i < 2; ++i) {// let(leafCount = i) { /*do something*/ }}for (var i = 0; i < 2; ++i) {with(leafCount = i) { /*do something*/ }}};
var tree1 = new Tree(tree1Data);console.log(window);

防止重复:

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

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

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

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

语句"use 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. 禁止以任何形式绑定或分配名称evalarguments

  11. 严格模式不会将arguments对象的属性与形式参数别名。(例如,在function sum (a,b) { return arguments[0] + b;}中,这有效,因为arguments[0]绑定到a等等。)(请参阅下面的#4部分以了解差异

  12. arguments.callee不支持

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


示例:

  1. 严格模式代码不会别名其中创建的参数对象的属性
function show( msg ){msg = 42;console.log( msg );          // msg === 42console.log( arguments[0] ); // arguments === 42}show( "Hey" );
// In strict mode arguments[i] does not track the value of// the corresponding named argument, nor does a named argument track the value in the corresponding arguments[i]function showStrict( msg ){"use strict";msg = 42;console.log( msg );          // msg === 42console.log( arguments[0] ); // arguments === "Hey"}showStrict( "Hey" );

引自w3学校

“严格使用”指令

使用严格指令是JavaScript 1.8.5中的新指令(ECMAScript版本5)。

它不是一个语句,而是一个文字表达式,前面忽略了JavaScript版本。

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

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

为什么是严格模式?

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

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

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

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

在严格模式下,对不可写属性的任何赋值getter唯一属性,一个不存在的属性,一个不存在的属性变量或不存在的对象将抛出错误。

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

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

您可以参考MDN留档获取更多信息。

"use strict"在ECMAScript 5中引入的指令。

指令类似于语句,但又不同。

  • use strict不包含关键字:该指令是一个简单的表达式语句,由一个特殊的字符串文字(单引号或双引号)组成。不实现ECMAScript 5的JavaScript引擎只看到一个没有副作用的表达式语句。预计未来版本的ECMAScript标准会引入use作为真正的关键字;引号将因此过时。
  • use strict只能在脚本或函数的开头使用,即它必须在其他所有(真实)语句之前。它不必是函数脚本中的第一条指令:它可以在其他由字符串文字组成的语句表达式之前(JavaScript实现可以将它们视为实现特定的指令)。字符串文字语句跟随第一个真实语句(在脚本或函数中)是简单的表达式语句。解释器不能将它们解释为指令,它们没有效果。

use strict指令表示以下代码(在脚本或函数中)是严格代码。当脚本包含use strict指令时,脚本最高级别的代码(不在函数中的代码)被视为严格代码。当函数本身在严格代码中定义或函数包含use strict指令时,函数的内容被视为严格代码。当从严格代码调用eval()或包含use strict指令本身时,传递给eval()方法的代码被视为严格代码。

ECMAScript 5的严格模式是JavaScript语言的一个受限子集,它消除了语言的相关缺陷,并具有更严格的错误检查和更高的安全性。以下列出了严格模式和正常模式之间的区别(其中前三个特别重要):

  • 您不能在严格模式下使用with-语句。
  • 在严格模式下,所有变量都必须声明:如果您将一个值分配给尚未声明为全局Object的变量、函数、函数参数、catch-子句参数或属性的标识符,那么您将获得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()完成执行后被销毁。

  • 在严格模式下,函数的参数对象包含传递给该函数的值的静态副本。在正常模式下,参数对象具有某种“神奇”的行为:数组的元素和命名函数参数引用相同的值。

  • 在严格模式下,当delete运算符后跟一个非限定标识符(变量、函数或函数参数)时,您将获得SyntaxError。在正常模式下,delete表达式什么也不做,并被计算为false

  • 在严格模式下,当您尝试删除不可配置的属性时,您将获得TypeError。(在正常模式下,尝试简单失败,delete表达式的计算结果为false)。

  • 在严格模式下,当您尝试为对象文字定义多个同名属性时,它被认为是语法错误。(在正常模式下没有错误。)

  • 在严格模式下,当函数声明有多个同名参数时,它被认为是语法错误。(在正常模式下没有错误。)

  • 在严格模式下,不允许八进制文字(这些是以0开头的文字。(在正常模式下,一些实现确实允许八进制文字。)

  • 在严格模式下,标识符evalarguments被视为关键字。您不能更改它们的值,不能为它们赋值,也不能将它们用作捕获块的变量、函数、函数参数或标识符的名称。

  • 在严格模式下,对检查调用堆栈的可能性有更多限制。arguments.callerarguments.callee会在严格模式下的函数中导致TypeError。此外,严格模式下函数的一些调用者和参数属性会在您尝试读取它们时导致TypeError

添加"use strict";时,以下情况将在脚本执行之前抛出语法错误

  • 为未来的ECMAScript版本铺平道路,使用新保留的关键字之一(在ECMAScript 6的预览中):implementsinterfaceletpackageprivateprotectedpublicstaticyield

  • 在块中声明函数

    if(a<b){ function f(){} }
  • Octal syntax

    var n = 023;
  • this point to the global object.

     function f() {"use strict";this.a = 1;};f();
  • Declaring twice the same name for a property name in an object literal

     {a: 1, b: 3, a: 7}

    在ECMAScript 6(bug1041128)中不再是这种情况。

  • 声明两个同名函数参数

    f(a, b, b){}
  • Setting a value to an undeclared variable

    function f(x){"use strict";var a = 12;b = a + x*35; // error!}f();
  • Using delete on a variable name delete myVariable;

  • Using eval or arguments as variable or function argument name

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

Sources:

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

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

'use strict';

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

考虑这个例子:

var a = 365;var b = 030;

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

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


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

  • 在我的新的 JavaScript应用程序中:绝对是!严格模式可以用作告密者,当你用你的代码做一些愚蠢的事情时。

  • 在我的现有 JavaScript代码中:大概不会吧!如果您现有的JavaScript代码有严格模式下禁止的语句,应用程序将简单地中断。如果您想要严格模式,您应该准备调试和纠正现有代码。这就是为什么使用#0不会突然让你的代码变得更好


如何使用严格模式?

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

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

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

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

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

    函数doSomething词汇范围中的所有内容都将以严格模式解释。词汇范围这个词在这里很重要。例如,如果您的严格代码调用了不严格库的函数,那么只有您的代码会以严格模式执行,而不是被调用的函数。有关更好的解释,请参阅这个答案


严格模式下禁止哪些东西?

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

范围

从历史上看,JavaScript一直困惑于功能有时它们似乎是静态范围的,但有些特性使它们表现得像是动态作用域。这是混乱,使程序难以阅读和理解。误解会导致bug,对性能也是个问题。静态作用域允许变量绑定在编译时发生时间,但对动态范围的要求意味着绑定必须是推迟到运行时,这带来了显着的性能罚款。

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

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

隐含全局变量

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

全球渗漏

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

噪音故障

JavaScript一直具有只读属性,但您无法自己创建它们,直到ES5的Object.createProperty函数暴露了该功能。如果您尝试分配值对于只读属性,它将静默失败。赋值将不会更改属性的值,但您的程序将继续执行这是一个完整性风险,可以导致程序进入不一致状态。在严格模式下,试图更改只读属性将引发异常。

八进制

数字的八进制(或基数8)表示非常在机器上进行机器级编程时很有用-尺寸是3的倍数-你和CDC合作时需要八进制6600主机,字长为60位。如果你能阅读八进制,您可以将一个单词视为20位数字。两位数字代表操作代码和一个数字标识了8个寄存器中的一个。在从机器代码到高级语言的缓慢过渡,它是认为在编程语言中提供八进制形式很有用。

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

等等

参数伪数组变得更多了ES5中的类数组。在严格模式下,它失去了calleecaller属性。这使得将您的arguments传递给不受信任的人成为可能代码而不会放弃很多机密上下文。此外,arguments函数属性被消除。

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


为未来的JavaScript版本保留单词

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

implementsinterfaceletpackageprivateprotectedpublicstaticyield


进一步阅读

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

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

  • 全局代码是严格模式代码,如果它以包含使用严格指令的指令序言开头(见14.1.1)。
  • 模块代码始终是严格模式代码。
  • 类声明类表达式的所有部分都是严格模式代码。
  • Eval代码是严格模式代码,如果它以包含使用严格指令的指令序幕开头,或者如果对ava的调用是包含在严格模式代码中的直接val(请参阅12.3.4.1)。
  • 如果关联的函数声明、函数表达式、生成器声明、生成器表达式、方法定义或箭头函数包含在严格模式代码中,或者如果生成函数[[ECMAScriptCode]]内部槽值的代码以包含使用严格指令的指令序言开头,则函数代码是严格模式代码。
  • 作为内置函数和生成器构造函数的参数提供的函数代码是严格模式代码,如果最后一个参数是一个字符串,当处理时是一个功能配置,以包含使用严格指令的指令序言开头。

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

use strict是一种让你的代码更安全的方法,因为你不能使用那些不能像你期望的那样工作的危险特性。而且,正如前面所写的,它使代码更加严格。

要比较的小例子:

非严格模式:

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

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

  • 防止意外全局变量

  • 没有重复

  • 消除与

  • 消除了这种强迫

  • 更安全的评估()

  • 不可变错误

您也可以阅读此文章以了解详细信息

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

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

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

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

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

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

use strict也适用于单个函数。在代码中包含use strict总是更好的做法。

浏览器兼容性问题:“use”指令旨在向后兼容。不支持它们的浏览器只会看到一个没有进一步引用的字符串文字。因此,他们将忽略它并继续前进。

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

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

    function useStrictDemo(){'use strict';//works finevar a = 'No Problem';
    //does not work fine and throws errork = "problem"
    //even this will throw errorsomeObject = {'problem': 'lot of problem'};}
  2. N.B: The "use strict" directive is only recognized at the beginning of a script or a function.
  3. The string "arguments" cannot be used as a variable:

    "use strict";var arguments = 3.14;    // This will cause an error
  4. Will restrict uses of keywords as variables. Trying to use them will throw errors.

In short will make your code less error prone and in turn will make you write good code.

To read more about it you can refer here.

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

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

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

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

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

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

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

使用“使用严格”的示例:
函数的严格模式:同样,为一个函数调用严格模式函数中,将确切的语句“使用严格”;(或“使用严格”;)放在在任何其他语句之前的函数体。

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 globalvar undefined = 5; // throws a TypeErrorvar Infinity = 5; // throws a TypeError
// Assignment to a non-writable propertyvar obj1 = {};Object.defineProperty(obj1, 'x', { value: 42, writable: false });obj1.x = 9; // throws a TypeError
// Assignment to a getter-only propertyvar 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

使用严格;定义JavaScript代码应该在严格模式。

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

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

缺点

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

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

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

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

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

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

function getname(){name = "Stack Overflow"; // Not using var keywordreturn name;}getname();console.log(name); // Stack Overflow

在这个函数中,我们在函数内部使用了一个名为name的变量。在内部,编译器将首先检查在该特定函数范围内是否有以该特定名称声明的变量。由于编译器理解没有这样的变量,它将在外部范围内检查。在我们的案例中,它是全局范围。同样,编译器理解在全局空间中也没有以该名称声明的变量,所以它在全局空间为我们创建了这样一个变量。从概念上讲,这个变量将在全局范围内创建,并在整个应用程序中可用。

另一种情况是,比如说,变量在子函数中声明。在这种情况下,编译器会在外部作用域(即父函数)检查该变量的有效性。只有这样,它才会检查全局空间并在那里为我们创建一个变量。这意味着需要进行额外的检查。这将影响应用程序的性能。


现在让我们在严格模式下编写相同的函数。

"use strict"function getname(){name = "Stack Overflow"; // Not using var keywordreturn name;}getname();console.log(name);

我们将得到以下错误。

Uncaught ReferenceError: name is not definedat getname (<anonymous>:3:15)at <anonymous>:6:5

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

严格模式消除了在非严格模式下会被忽略的错误,从而使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代码。然而,作为开发人员,我不想在我的代码中留下bug,因为我知道它可能会回来咬我,而我也只想写出好的代码。这就是严格模式帮助的地方。

场景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语言中的保留字在严格模式下。这些词是实现接口、let、包、私有、保护、公共。静态和产量

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

由于浏览器大战和糟糕的管理,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"指令。这是设计的。

严格模式在v8引擎中启用严格功能。一些功能的简短示例:

您可以通过以下方式在全局启用它:

'use strict'; // strict mode enabled!

每个函数您只需在函数中包含:

let myfunc = () => {'use strict'; // strict mode enabled  
b = 0; // broke}
  • 您必须在使用它之前声明一个变量(sane imo):
  var x;x = '0'; // oky = '';  // not ok
  • 启用es6功能(这取决于浏览器),对于节点v4+这很重要。

  • 在某些情况下,性能更好。

还有更多的功能,检查这里更多!

要对整个脚本使用严格模式,请将确切语句use strict;在任何其他声明之前。