JavaScript中使用“use strict”是什么,背后的原因是什么?

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

第1行的问题1:缺少“use strict”声明。

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

那么,究竟是"use strict";什么意思,这是什么意思,而且还是相关的?

目前的浏览器是否有响应这个"use strict";字符串,还是为了将来的使用?

这篇关于Javascript Strict Mode的文章可能会让你感兴趣:John Resig – ECMAScript 5严格模式,JSON等等

引用一些有趣的部分:

严格模式是ECMAScript 5中的一项新功能,允许您在“严格”操作环境中放置程序或函数。这种严格的上下文阻止了某些动作被采取并抛出了更多的异常。

和:

严格的模式可以帮助你:

  • 它捕获了一些常见的编码bloopers,抛出异常。
  • 当相对“不安全”的行为被采取时(例如获得对全局对象的访问),它防止或抛出错误。
  • 它禁用混淆或糟糕的功能。

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

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 
  1. 改变这么多年后的默认值?为时太晚:它会打破许多现有的网站/脚本/应用程序…唯一可能的事情是帮助事情变好,为未来。
  2. 我尝试了一个小的代码片段,"use strict"在Firefox 3.6,Safari 5,Chrome 7和Opera 10.6(全部Mac)中使用时将无效。没有任何错误,所以我想’使用严格’是不支持任何浏览器。虽然没有在IE9中测试)
  3. Chrome浏览器11似乎通过所有这些测试一样IE10 ie.microsoft.com/testdrive/HTML5/TryStrict/Default.html# –  GMAN
  4. 这触发了我的ocd …想切换语言规范?不要使用保留的关键字!只要把一根随机的字符串从任何地方乱转到无处,它就会诀窍。
  5.  这不能使用保留关键字来实现,因为那么尝试触发严格模式的代码会在旧浏览器中中断。添加一个“随机”字符串文字不会破坏任何东西。

 

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

这只是一个字符串,你放在你的JavaScript文件(无论是在你的文件的顶部或函数内),看起来像这样:

"use strict";

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

该语句"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等。)
  12. arguments.callee 不被支持

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

 

如果人们担心使用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.
*/

 

谨慎的一句话,你所有的程序员都很费劲:应用"use strict"到现有的代码可能是危险的!这个东西不是一些感觉良好的,快乐的贴纸,你可以在代码上拍一下,让它“更好”。使用"use strict"编译指示,浏览器会突然在随机的地方突然抛出异常,这是因为在那个地方,你正在做一些默认的/松散的JavaScript,但严格的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"声明而成为红色标记,但现在已经过去了几年。

 

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

显然,在最初阶段会出现我们以前从未遇到过的错误。为了获得充分的利益,我们需要在切换到严格模式之后做适当的测试,以确保我们抓住了一切。当然,我们不只是抛出use strict我们的代码,并假设没有错误。因此,现在是时候开始使用这个令人难以置信的有用的语言功能来编写更好的代码。

例如,

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

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

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

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

'use strict';

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

考虑这个例子:

var a = 365;
var b = 030;

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

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

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

  • 在我的新的 JavaScript应用程序中:绝对!严格的模式可以用来作为举报人,当你正在做你的代码愚蠢的东西。
  • 在我现有的 JavaScript代码中:可能不是!如果您现有的JavaScript代码有严格模式禁止的语句,则应用程序将会中断。如果你想要严格的模式,你应该准备好调试和纠正你现有的代码。这就是为什么使用'use strict';不会突然让你的代码更好

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

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

'use strict';

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

考虑这个例子:

var a = 365;
var b = 030;

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

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


我应该在哪里使用'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将以严格的模式进行解释。词汇范围这个词在这里很重要。看到这个答案更好的解释。


严格模式禁止什么东西?

我发现了一篇很好的文章,描述了在严格模式下禁止的几件事情(请注意,这不是一个独占列表):

范围

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

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

严格代码的好处之一就是像YUI压缩 器这样的工具在处理时可以做得更好。

隐含的全局变量

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

全球泄漏

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

嘈杂的失败

JavaScript一直拥有只读属性,但是直到ES5的Object.createProperty 功能暴露出来才能创建它们。如果您试图将值分配给只读属性,则会失败。这个任务不会改变这个属性的值,但是你的程序会像进程一样继续。这是一种完整性危害,可能导致程序进入不一致的状态。在严格模式下,尝试更改只读属性将引发异常。

八进制

在字大小为3的倍数的机器上进行机器级编程时,八进制(或基数为8)的数字表示非常有用。在使用CDC 6600主机时,需要八进制数,其大小为60位。如果你可以读八进制,你可以看一个单词20位数字。两个数字表示操作码,一个数字表示8个寄存器之一。在从机器代码到高级语言的慢速转换过程中,认为在编程语言中提供八进制形式是有用的。

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

等等

在ES5中,参数伪数组变得更像数组。在严格模式下,它失去了它calleecaller 属性。这样就可以将您的arguments代码传递给不可信任的代码,而不必放弃很多机密的上下文。而且,arguments功能的 属性被消除了。

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


未来JavaScript版本的保留字

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

implementsinterfaceletpackageprivateprotectedpublicstatic,和yield

添加评论

友情链接:蝴蝶教程