javascript - strict什么意思 - use strict是什么意思使用它的好处和坏处分别是什么




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

使用'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 Compressor这样的工具在处理它时可以做得更好。

隐含的全局变量

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

全球泄漏

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

吵闹失败

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添加了一个保留字列表。 如果将它们用作变量或参数,则严格模式将引发错误。 保留字是:

implementsinterfaceletpackageprivateprotectedpublicstaticyield

进一步阅读

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

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

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

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

当前任何浏览器都会响应"use strict"; 字符串或将来使用?


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


引自w3schools

“使用严格”指令

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

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

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

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

为何选择严格的模式?

严格模式可以更轻松地编写“安全”JavaScript。

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

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

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

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

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


"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”; (或'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上阅读更多内容


我的两分钱:

严格模式的目标之一是允许更快地调试问题。 它可以帮助开发人员在发生某些可能导致网页无声和奇怪行为的错误事件时抛出异常。 当我们使用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

消除声明:

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

Sample

防止重复:

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

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

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

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


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

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

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

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

了解更多信息vistit Strict Mode- Javascript


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

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

写“使用严格”; 在JS文件的最顶层打开严格的语法检查。它为我们完成以下任务:

(i)如果您尝试分配未声明的变量,则会显示错误

(ii)阻止您覆盖关键的JS系统库

(ii)禁止一些不安全或容易出错的语言功能

“use strict”也适用于个别功能。在代码中包含“严格使用”总是更好的做法。

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


声明"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开发者网络 ]


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

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


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

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

例如,

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

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


比较小例子:

非严格模式:

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

添加"use strict"; ,以下情况将在脚本执行之前抛出一个SyntaxError

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

  • 在块中声明函数

    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;

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

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

资料来源:


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

引用一些有趣的部分:

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

和:

严格模式有两种方式:

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

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

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 

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

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

目前,它受到所有主流浏览器支持 (IE 9及以下版本)


需要注意的是,所有硬编程程序员:对现有代码应用"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"声明而成为红色标记,但现在还需要几年的时间。


一些参与ECMAScript委员会的人员进行了很好的讨论:JavaScript的变化,第1部分:ECMAScript 5“关于"use strict"交换机的增量使用如何允许JavaScript实施者清理JavaScript的许多危险特性而不会突然破坏每个网站在世界上。

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


开发人员应该使用的主要原因"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. 将限制使用关键字作为变量。试图使用它们会引发错误。

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

要了解更多信息,请参阅此处


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

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





use-strict