最近,我通过Crockford的JSLint运行了一些我的JavaScript代码,它给出了以下错误:
第1行问题1:缺少“使用严格”声明。
做一些搜索,我意识到有些人将"use strict";
添加到他们的JavaScript代码中。一旦我添加了语句,错误就会停止显示。不幸的是,谷歌没有透露这个字符串声明背后的历史。当然它必须与浏览器如何解释JavaScript有关,但我不知道效果会是什么。
那么什么是"use strict";
,它意味着什么,它仍然相关吗?
当前的任何浏览器都会响应"use strict";
字符串,还是将来使用?
这篇关于Javascript Strict Mode的文章可能会让您感兴趣:John Resig - ECMAScript 5 Strict Mode, JSON, and More
引用一些有趣的部分:
严格模式是ECMAScript 5中的一项新功能,允许您在“严格”操作上下文中放置程序或函数。这种严格的上下文阻止了某些操作被采取并引发更多异常。
和:
严格模式有两种方式:
- 它捕获了一些常见的编码bloopers,抛出异常。
- 当采取相对“不安全”的操作(例如获取对全局对象的访问权限)时,它会阻止或抛出错误。
- 它禁用令人困惑或思索不周的功能。
另请注意,您可以对整个文件应用“严格模式”...或者您只能将其用于特定功能(仍然引用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中编写JavaScript(使用import
和export
语句),则始终启用严格模式,并且无法禁用。
如果您使用过去一年左右发布的浏览器,那么它很可能支持JavaScript Strict模式。只有在ECMAScript 5成为当前标准之前的旧浏览器才支持它。
命令周围的引号确保代码仍然可以在旧版浏览器中工作(尽管在严格模式下生成语法错误的事情通常只会导致脚本在这些旧版浏览器中以某种难以检测的方式出现故障)。
添加"use strict";
时,以下情况将在脚本执行之前抛出SyntaxError:
implements
,interface
,let
,package
,private
,protected
,public
,static
和yield
。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;
eval
或arguments
作为变量或函数参数名称
"use strict";
arguments++;
var obj = { set p(arguments) { } };
try { } catch (arguments) { }
function arguments() { }
资料来源:
严格模式对常规JavaScript语义进行了一些更改:
欲了解更多信息,请访问qazxsw poi
“使用严格”;是程序员不会使用JavaScript的松散或不良属性的保险。这是一个指南,就像一个统治者将帮助你做直线。 “使用严格”将帮助您进行“直接编码”。
那些不想使用统治者直接行直线的人通常会在那些要求其他人调试代码的页面中结束。
相信我。与设计不良的代码相比,开销可以忽略不计。 Strict Mode- Javascript。就个人而言,我喜欢一直回到他的网站,以确保我不忘记我的良好做法。
现代JavaScript实践应该总是唤起“使用严格”;附注。 ECMA集团选择“严格”模式的唯一原因是允许经验较少的编码人员访问JavaScript,然后有时间适应新的更安全的编码实践。
从这一点开始,在所有敏感JavaScript文件的开头包含Doug Crockford, who has been a senior JavaScript developer for several years, has a very interesting post here是一个很好的方法,可以成为一个更好的JavaScript程序员,并避免随机变量变为全局变量,并且事情会发生变化。
use strict
:
“使用严格”指令
“use strict”指令是JavaScript 1.8.5(ECMAScript版本5)中的新指令。
它不是一个语句,而是一个文字表达式,被早期版本的JavaScript忽略。
“use strict”的目的是表明代码应该以“严格模式”执行。
例如,使用严格模式,您不能使用未声明的变量。
为何选择严格的模式?
严格模式可以更轻松地编写“安全”JavaScript。
严格模式将以前接受的“错误语法”更改为实际错误。
例如,在普通的JavaScript中,错误输入变量名称会创建一个新的全局变量。在严格模式下,这将引发错误,从而无法意外创建全局变量。
在普通的JavaScript中,开发人员不会收到任何错误反馈,将值分配给不可写属性。
在严格模式下,对非可写属性,仅getter属性,不存在的属性,不存在的变量或不存在的对象的任何赋值都将引发错误。
请参阅Quoting from w3schools了解更多信息
http://www.w3schools.com/js/js_strict.asp使JavaScript代码以严格模式运行,这基本上意味着在使用之前需要定义所有内容。使用严格模式的主要原因是避免未定义方法的意外全局使用。
在严格模式下,事情运行得更快,一些警告或无声警告会导致致命错误,最好总是使用它来制作更整洁的代码。
"use strict"
在ECMA5中被广泛使用,在ECMA6中它默认是JavaScript的一部分,所以如果你使用ES6则不需要添加它。
查看MDN的这些陈述和示例:
“使用严格”指令 “use strict”指令是JavaScript 1.8.5(ECMAScript版本5)中的新指令。它不是一个语句,而是一个文字表达式,被早期版本的JavaScript忽略。 “use strict”的目的是表明代码应该以“严格模式”执行。例如,使用严格模式,您不能使用未声明的变量。
使用“use strict”的例子: 函数的严格模式:同样,要为函数调用严格模式,请输入确切的语句“use strict”; (或'use strict';)在任何其他语句之前在函数体中。
1)功能严格模式
"use strict"
2)全脚本严格模式
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());
3)分配给不可写的全局
'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);
你可以'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
。
有一些人参加了ECMAScript委员会的讨论:read more on MDN关于Changes to JavaScript, Part 1: ECMAScript 5"交换机的增量使用如何允许JavaScript实施者清理JavaScript的许多危险特性而不会突然破坏世界上的每个网站。
当然,它还讨论了很多这些错误信息是什么以及ECMAScript 5如何修复它们。
请注意,"use strict"
是在use strict
中引入的,并且从那时开始保存。
以下是在EcmaScript 5和ES6中触发严格模式的条件:
- 全局代码是严格模式代码,如果它以包含使用严格指令的指令序言开头(见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,处理时是一个以包含Use Strict指令的Directive Prologue开头的FunctionBody。
要比较的小例子:
非严格模式:
严格模式:
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
这是ECMAScript 5的一个新功能.John Resig写了它的a nice summary。
它只是一个放在JavaScript文件中的字符串(位于文件顶部或函数内部),如下所示:
"use strict";
现在将它放在你的代码中不应该导致当前浏览器出现任何问题,因为它只是一个字符串。如果您的代码违反了编译指示,将来可能会导致您的代码出现问题。例如,如果您目前没有首先定义foo = "bar"
的foo
,那么您的代码将开始失败......在我看来这是一件好事。
开发人员应该使用String.prototype.test = function () {
'use strict';
console.log(typeof this === 'string');
};
'a'.test();
// output
// true
的主要原因是:
"use strict"
将确保在使用前使用"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'};
}
指令仅在脚本或函数的开头被识别。"use strict"
不能用作变量:
"arguments"
简而言之,这将使您的代码不易出错,反过来会让您编写好的代码。
要了解更多信息,请参阅"use strict";
var arguments = 3.14; // This will cause an error
。
“严格使用”;是ECMA努力使JavaScript更加强大。它引入了JS,试图使其至少有一点“严格”(其他语言自90年代起实施严格的规则)。它实际上“迫使”JavaScript开发人员遵循某种编码最佳实践。 JavaScript仍然非常脆弱。没有类型化变量,类型化方法等。我强烈建议JavaScript开发人员学习更强大的语言,如Java或ActionScript3,并在JavaScript代码中实现相同的最佳实践,它将更好地工作并且更容易调试。
qazxsw poi是一种让你的代码更安全的方法,因为你不能使用危险的功能,这些功能可能不会像你期望的那样工作。并且正如之前所写,它使代码更加严格。
使用Strict用于显示常见错误和重复错误,以便以不同方式处理,并更改java脚本运行的方式,此类更改包括:
你也可以阅读这个here了解详情
通常,JavaScript不遵循严格的规则,因此增加了错误的可能性。在使用use strict
之后,JavaScript代码应遵循严格的规则集,如在其他编程语言中一样,例如使用终结符,初始化之前的声明等。
如果使用article,则应遵循严格的规则集编写代码,从而减少错误和模糊的可能性。
ECMAScript 5中引入了JavaScript“严格”模式。
"use strict"
在JS文件的最顶层编写"use strict"
会打开严格的语法检查。它为我们完成以下任务:
(function() {
"use strict";
your code...
})();
也在个人职能范围内工作。在代码中包含"use strict";
总是更好的做法。
浏览器兼容性问题:“use”指令旨在向后兼容。不支持它们的浏览器只会看到一个未被进一步引用的字符串文字。所以,他们会过去并继续前进。
“严格使用”;定义JavaScript代码应该以“严格模式”执行。
除Internet Explorer 9及更低版本外,所有现代浏览器都支持“use strict”。
坏处
如果开发人员使用处于严格模式的库,但开发人员习惯于以正常模式工作,他们可能会在库上调用一些无法按预期工作的操作。
更糟糕的是,由于开发人员处于正常模式,他们没有抛出额外错误的优势,因此错误可能会无声地失败。
此外,如上所列,严格模式会阻止您执行某些操作。
人们通常认为你不应该首先使用这些东西,但是一些开发人员不喜欢这种约束并希望使用该语言的所有功能。
use strict
声明"use strict";
指示浏览器使用Strict模式,这是一种简化且更安全的JavaScript功能集。
var
声明和拼写错误)NaN = 5;
)delete Object.prototype
)var x = {x1: "1", x1: "2"}
)function sum (x, x) {...}
)var x = 023;
,一些开发者错误地认为前面的零不会改变数字。)with
关键字eval
不会引入新的变量delete x;
)eval
和arguments
arguments
对象的属性。 (即在function sum (a,b) { return arguments[0] + b;}
这是有效的,因为arguments[0]
绑定到a
等等。)arguments.callee
不受支持[参考:Strict mode,Mozilla开发者网络]
如果人们担心使用use strict
,可能值得查看这篇文章:
ECMAScript 5 'Strict mode' support in browsers. What does this mean? 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憎恶的东西!您可能会在代码中隐藏很少使用的严格违规,只会在最终运行时抛出异常 - 例如,在付费客户使用的生产环境中!
如果您想采取措施,最好将"use strict"
与全面的单元测试和严格配置的JSHint构建任务结合使用,这将使您确信模块中没有黑暗的角落会因为可怕而爆炸你打开了严格模式。或者,嘿,这是另一种选择:只是不要将"use strict"
添加到任何遗留代码中,它可能更安全,老实说。绝对不要将"use strict"
添加到您不拥有或维护的任何模块,例如第三方模块。
我认为即使它是一种致命的笼养动物,"use strict"
可能是好东西,但你必须做得对。严格要求的最佳时机是您的项目是绿地并且您从头开始。配置JSHint/JSLint
时,所有的警告和选项都会随着团队的紧张而变得紧张,得到一个良好的构建/测试/断言系统,如Grunt+Karma+Chai
,并且只有THEN开始将所有新模块标记为"use strict"
。准备好治愈许多琐碎的错误和警告。如果JSHint/JSLint
产生任何违规,请确保每个人都了解重力,将构建配置为FAIL。
当我采用"use strict"
时,我的项目不是一个绿地项目。结果,我的IDE充满了红色标记,因为我的一半模块上没有"use strict"
,而JSHint抱怨这一点。这提醒我一下我将来应该做什么重构。我的目标是由于我所有遗失的"use strict"
陈述而成为红色标记,但现在已经过去了几年。
'use strict';
does not suddenly make your code better.JavaScript strict mode是ECMAScript 5的一个特色。您可以通过在脚本/函数的顶部声明这个来启用严格模式。
'use strict';
当JavaScript引擎看到此指令时,它将开始以特殊模式解释代码。在这种模式下,当检测到可能最终成为潜在错误的某些编码实践时(这是严格模式背后的原因),会引发错误。
考虑这个例子:
var a = 365;
var b = 030;
在他们对数字文字排列的痴迷中,开发人员无意中用八进制文字初始化了变量b
。非严格模式会将其解释为值为24
的数字文字(在基数10中)。但是,严格模式会抛出错误。
有关严格模式的非专业清单,请参阅this answer。
'use strict';
?'use strict';
不会突然使你的代码变得更好。'use strict';
语句:
// File: myscript.js
'use strict';
var a = 2;
....
请注意,文件myscript.js
中的所有内容都将以严格模式进行解释。'use strict';
语句:
function doSomething() {
'use strict';
...
}
函数doSomething
的词法范围内的所有内容都将以严格模式进行解释。词汇范围这个词在这里很重要。有关更好的解释,请参阅this answer。我发现了一个nice article描述了严格模式中禁止的几个事项(请注意,这不是一个独家列表):
范围
从历史上看,JavaScript一直困扰着函数的作用域。有时它们似乎是静态范围的,但有些功能使它们的行为类似于动态范围。这令人困惑,使程序难以阅读和理解。误解会导致错误。这也是性能问题。静态作用域允许在编译时发生变量绑定,但是对动态作用域的要求意味着必须将绑定延迟到运行时,这会带来显着的性能损失。
严格模式要求静态完成所有变量绑定。这意味着必须消除或修改以前需要动态绑定的功能。具体来说,删除了with语句,并且eval函数篡改其调用者环境的能力受到严格限制。
严格的代码的好处之一是像YUI Compressor这样的工具在处理它时可以做得更好。
隐含的全局变量
JavaScript隐含了全局变量。如果未显式声明变量,则会隐式声明全局变量。这使得初学者的编程更容易,因为他们可以忽略一些基本的家务杂务。但它使较大程序的管理变得更加困难,并且显着降低了可靠性。因此,在严格模式下,不再创建隐含的全局变量。您应该明确声明所有变量。
全球泄漏
有许多情况可能导致
this
绑定到全局对象。例如,如果在调用构造函数时忘记提供new
前缀,构造函数的this
将意外绑定到全局对象,因此它不是初始化新对象,而是静默地篡改全局变量。在这些情况下,严格模式会将this
绑定到undefined
,这将导致构造函数抛出异常,从而允许更快地检测到错误。吵闹失败
JavaScript一直都有只读属性,但是在ES5的
Object.createProperty
函数暴露出该功能之前,你无法自己创建它们。如果您尝试将值分配给只读属性,则它将以静默方式失败。赋值不会改变属性的值,但是程序会像它一样继续进行。这是一种完整性危害,可能导致程序进入不一致状态。在严格模式下,尝试更改只读属性将引发异常。八进制
当在字大小为3的倍数的机器上进行机器级编程时,数字的八进制(或基数8)表示非常有用。在使用CDC 6600大型机(字大小为60位)时,需要八进制。如果你可以读八进制,你可以看一个单词为20位数。两位数表示操作码,一位数字表示8个寄存器中的一个。在从机器代码到高级语言的缓慢过渡期间,认为在编程语言中提供八进制形式是有用的。
在C中,选择了非常不幸的八进制表示:前导零。所以在C中,
0100
意味着64而不是100,而08
是一个错误,而不是8.更不幸的是,这种时代错误被复制到几乎所有现代语言中,包括JavaScript,它只用于创建错误。它没有其他目的。因此在严格模式下,不再允许八进制形式。等等
参数伪数组在ES5中变得更像阵列。在严格模式下,它失去了
callee
和caller
属性。这使得可以将arguments
传递给不受信任的代码,而不会放弃大量的机密上下文。此外,消除了函数的arguments
属性。在严格模式下,函数文字中的重复键将产生语法错误。函数不能有两个具有相同名称的参数。函数不能具有与其参数之一具有相同名称的变量。一个函数不能
delete
自己的变量。尝试将delete
设置为不可配置的属性现在会抛出异常。原始值不是隐式包装的。
ECMAScript 5添加了一个保留字列表。如果将它们用作变量或参数,则严格模式将引发错误。保留字是:
implements
,interface
,let
,package
,private
,protected
,public
,static
和yield
我强烈建议每个开发人员现在开始使用严格模式。有足够的浏览器支持它,严格模式将合法地帮助我们避免我们甚至不知道你的代码中的错误。
显然,在初始阶段,我们以前从未遇到过错误。为了获得全部好处,我们需要在切换到严格模式后进行适当的测试,以确保我们已经捕获了所有内容。当然,我们不只是在代码中抛出use strict
并假设没有错误。所以,流失是时候开始使用这个非常有用的语言功能来编写更好的代码。
例如,
var person = {
name : 'xyz',
position : 'abc',
fullname : function () { "use strict"; return this.name; }
};
JSLint是Douglas Crockford编写的调试器。只需粘贴您的脚本,它就会快速扫描代码中的任何明显问题和错误。
我想提供一个更有根据的答案,补充其他答案。我希望编辑最流行的答案,但失败了。我试图让它尽可能全面和完整。
您可以参考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
语句。Object
属性的标识符赋值,那么您将得到一个ReferenceError
。在正常模式下,标识符被隐式声明为全局变量(作为全局Object
的属性)this
在作为函数(而不是方法)调用的函数中具有值undefined
。 (在正常模式下,this
总是指向全球Object
)。这种差异可用于测试实现是否支持严格模式:var hasStrictMode = (function() { "use strict"; return this===undefined }());
call()
或apply
调用函数时,this
正好是call()
or apply()
调用的第一个参数的值。 (在正常模式下,null
和undefined
被全局Object
替换,并且不是对象的值被投射到对象中。)TypeError
。 (在正常模式下,两者都会失败而没有错误消息。)eval()
时,您无法在调用者的范围内声明或定义变量或函数(正如您可以在正常模式下执行)。相反,为eval()
创建了一个新范围,变量和函数在该范围内。在eval()
完成执行后,该范围被销毁。SyntaxError
运算符后跟一个非限定标识符(变量,函数或函数参数)时,您将获得delete
。在正常模式下,delete
表达式什么都不做,并被评估为false
。TypeError
。 (在正常模式下,尝试只是失败,delete
表达式被评估为false
)。0x
开头的文字。(在正常模式下,某些实现允许八进制文字。)eval
和arguments
被视为关键字。您不能更改它们的值,不能为它们赋值,也不能将它们用作变量,函数,函数参数或catch块标识符的名称。arguments.caller
和arguments.callee
在严格模式下导致TypeError
。此外,当您尝试读取时,严格模式下函数的某些调用者和参数属性会导致TypeError
。我的两分钱:
严格模式的目标之一是允许更快地调试问题。它可以帮助开发人员在发生某些可能导致网页无声和奇怪行为的错误事件时抛出异常。我们使用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
消除with
声明:
使用with
等工具无法缩小uglify-js语句。他们也是deprecated并从未来的JavaScript版本中删除。
防止重复:
当我们有重复属性时,它会抛出异常
未捕获的SyntaxError:严格模式下不允许在对象文字中复制数据属性
"use strict";
var tree1Data = {
name: 'Banana Tree',
age: 100,
leafCount: 100000,
name:'Banana Tree'
};
还有更多,但我需要获得更多的知识。