JavaScript中使用”严格”做什么,背后的原因是什么?
最近,我通过Crockford的JSLint运行了一些我的JavaScript代码,它给出了以下错误:
做一些搜索,我意识到有些人会加入"use strict";
他们的JavaScript代码.一旦我添加了语句,错误就会停止显示.不幸的是,谷歌没有透露这个字符串声明背后的历史.当然它必须与浏览器如何解释JavaScript有关,但我不知道效果会是什么.
那么它是"use strict";
什么,它意味着什么,它是否仍然相关?
当前的任何浏览器都会响应"use strict";
字符串还是将来使用?
回答
这篇关于Javascript Strict Mode的文章可能会让您感兴趣:John Resig - ECMAScript 5 Strict Mode,JSON等
引用一些有趣的部分:
和:
- 它捕获了一些常见的编码bloopers,抛出异常.
- 当采取相对"不安全"的操作(例如获取对全局对象的访问权限)时,它会阻止或抛出错误.
- 它禁用令人困惑或思索不周的功能.
另请注意,您可以对整个文件应用"严格模式"...或者您只能将其用于特定功能(仍然引用John Resig的文章):
// Non-strict code... (function(){ "use strict"; // Define your library strictly... })(); // Non-strict code...
如果你必须混合旧代码和新代码,这可能会有所帮助;-)
所以,我认为它有点像"use strict"
你可以在Perl中使用(因此名称?):通过检测可能导致破坏的更多事情,它可以帮助您减少错误.
目前,它受到所有主流浏览器 的支持(IE 9及以下版本).
- 这么多年后改变默认值?太迟了:它会打破这么多现有的网站/脚本/应用程序......唯一可能的事情是帮助改善未来的事情.
- Chrome 11似乎和IE10一样通过了所有这些测试http://ie.microsoft.com/testdrive/HTML5/TryStrict/Default.html#
- 我尝试了一个小代码片段,在Firefox 3.6,Safari 5,Chrome 7和Opera 10.6(所有Mac)中使用"use strict"时会无效.没有任何错误,所以我猜任何浏览器都不支持'use strict'.虽然没有在IE9中测试;)
- @Julius - 这可能不是使用保留关键字实现的,因为尝试触发严格模式的代码会在旧浏览器中中断.添加"随机"字符串文字不会破坏任何内容.
- 快速更新:Firefox 4完全支持严格模式,据我所知,没有其他浏览器可以.Safari和Chrome有"部分"支持,但我真的不知道这意味着什么.
- 对于阅读这些评论的人:上面有人说他们在开发中使用严格模式但是将其删除以进行生产.这样做并不是一个好主意:在严格模式下执行的代码可以在非严格模式下以*不同*运行.**严格模式不是非严格模式的子集**,它会改变代码的运行方式.
- @ SpYk3HH那么这就意味着你已经使用了正确的习语.顺便说一句,这很好,但验证总是更好.这就是"使用严格"的含义.它验证你使用了正确的习语.您是否愿意顺从正确,或者证明是正确的?
- 我在开发过程中使用"use strict",并在生产过程中删除.
- "use strict";如果IE 7+支持不是必需的,那么写一个更好的javascript是一个好习惯.
- @ SpYk3HH如果你的js是专业的,那么就没有理由不使用"严格",使用它只能保护你的原始代码不受专业干扰的影响.
- @ SpYk3HH已经是Javascript专家的人不是目标受众,因为你不太可能犯那些"使用严格"应该阻止的愚蠢错误.就像Bjarne Stroustrup在谈论他如何在"g ++"中打开警告一样.好吧,呃.
- 最近的发展建议使用谷歌研发团队在V8上提出的"使用强大"功能:https://developers.google.com/v8/experiments - 这会强制功能子集策略因性能原因消除某些歧义
- 严格模式也可能会大大提高性能http://stackoverflow.com/questions/38411552/why-use-strict-improves-performance-10x-in-this-example
- @kiranvj分发生产版本时,请不要删除“ use strict”。“严格使用”模式所做的一项基本操作可以极大地提高整体性能,因为它告诉浏览器,没有“ eval”语句会将新变量引入范围。是否实际使用“ eval”(永远不要使用)并不重要。重要的是无法“严格使用”会阻止浏览器做出此假设,因为如果您调用的属性是伪装的,该怎么办?可能不是,但是浏览器无法做出此假设,因为它可能会破坏一些代码
这是ECMAScript 5的一个新功能.John Resig写了一个很好的摘要.
它只是一个放在JavaScript文件中的字符串(位于文件顶部或函数内部),如下所示:
"use strict";
现在将它放在你的代码中不应该导致当前浏览器出现任何问题,因为它只是一个字符串.如果您的代码违反了编译指示,将来可能会导致您的代码出现问题.例如,如果您目前foo = "bar"
没有foo
先定义,那么您的代码将开始失败......在我看来这是一件好事.
- 快速失败并大声失败.
- 如果您在HTML文件中编写内联Javascript,请使用`<script>"use strict";`启动每个新块.该标志仅适用于包含它的块.
- 这很有趣,这导致字符串必须有单引号.所以写''use strict';`代替
该语句"use strict";
指示浏览器使用Strict模式,这是一种简化且更安全的JavaScript功能集.
功能列表(非详尽)
[参考:严格模式,Mozilla开发者网络 ]
- Nit:允许全局变量,只需要显式(例如`window.foo = bar`).
- The example for 11. is unclear, it's not clear what the difference in strict mode is.
- 您在11中的示例缺少对的修改(否则就没有意义)。即 函数sum(a,b){a = 0; 返回参数[0] + b; } alert(sum(1,2))由于混叠将返回严格模式3和严格模式2。
如果人们担心使用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.
*/
- 我不同意.我认为这说明了它非常有用的原因.实质上,这意味着它返回其功能而不是"窗口"
- 什么时候你想要用"这个"你不能用"窗口"定位的窗口?
- 在第二个`this`中实际上是`undefined`.
- 它指的是它自己.`this`属于它自己的函数而不是全局窗口
- 关键是你的JS程序会因为访问未定义的属性而开始失败,而不是在全局对象上默默地做错事.使跟踪细微错误变得更容易.
- @JamieHutber它不属于它自己的函数,你仍然可以将`this`绑定到任何东西.`"use strict"`仅在未指定`this`时禁用将`window`赋值给`this`的默认行为
- 杰米你最后的评论不正确.有或没有严格模式`this`可以指你喜欢的任何对象,这取决于你如何调用函数 - 这是首先在语言中使用它.
需要注意的是,所有的硬件程序员:应用"use strict"
现有代码都是危险的!这个东西不是一些感觉良好,快乐的贴纸,你可以拍打代码,让它"更好".有了"use strict"
编译指示,浏览器会突然发现以前从未投过的随机位置的异常只是因为在那个位置你正在做一些默认/松散JavaScript允许但严格的JavaScript憎恶的东西!您可能会在代码中隐藏很少使用的严格违规,只会在最终运行时抛出异常 - 例如,在付费客户使用的生产环境中!
如果您想要采取行动,最好同时应用"use strict"
全面的单元测试和严格配置的JSHint构建任务,这将使您确信模块中没有黑暗的角落会因为您而可怕地爆炸已经开启了Strict Mode.或者,嘿,这是另一个选择:只是不要添加"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*中的例外,为了善意!把它洒在像玉米片上的糖一样的代码上,是吗?没有!坏!应谨慎使用"use strict",最好只在您控制的代码中使用,该代码具有针对所有主要浏览器并且运行所有代码路径的单元测试.你有测试吗?好的,"使用严格"对你来说没问题,自己敲门.
- 就个人而言,我从来没有/很少_add_`"使用严格";`对现有代码.话虽这么说,当我从头开始编写新代码时,我几乎总是会使用它
- ...或者只是将"use strict"应用为代码的最后一遍,修复所有明显的问题,耸耸肩,说"足够好",然后把它拿出去制作:)
- 如果您已经在使用JSLint,那么您可能已经修复了大多数"use strict"会破坏内容的地方.
使用'use strict';
不会突然使您的代码更好.
在JavaScript的严格模式是一个功能的ECMAScript 5.您可以通过在脚本/函数的顶部声明这个来启用严格模式.
'use strict';
当JavaScript引擎看到此指令时,它将开始以特殊模式解释代码.在这种模式下,当检测到可能最终成为潜在错误的某些编码实践时(这是严格模式背后的原因),会引发错误.
考虑这个例子:
var a = 365;
var b = 030;
在他们对数字文字排列的痴迷中,开发人员无意中b
用八进制文字初始化变量.非严格模式会将其解释为具有值的数字文字24
(在基数10中).但是,严格模式会抛出错误.
有关严格模式的非专业清单,请参阅此答案.
我应该在哪里使用'use strict';
?
我如何使用严格模式?
-
// File: myscript.js 'use strict'; var a = 2; ....
请注意,文件中的所有内容都
myscript.js
将以严格模式进行解释. -
function doSomething() { 'use strict'; ... }
函数词法范围内的所有内容都
doSomething
将以严格模式进行解释.词汇范围这个词在这里很重要.请参阅此答案以获得更好的解释.
严格模式禁止哪些事情?
我发现了一篇很好的文章,描述了在严格模式下禁止的几件事(请注意,这不是一个独家列表):
范围
从历史上看,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
使用不可配置的属性现在会抛出异常.原始值不是隐式包装的.
未来JavaScript版本的保留字
ECMAScript 5添加了一个保留字列表.如果将它们用作变量或参数,则严格模式将引发错误.保留字是:
进一步阅读
- 严格模式 - JavaScript | MDN
- 浏览器支持严格模式
- 过渡到严格模式
- @UVM:strict-mode指令仅影响词法范围.即只声明它的文件/函数.如果你有另一个没有''use strict'`指令的文件/函数,它们将以非严格模式执行,即使是从以严格模式运行的函数调用时也是如此.有关说明,请参阅[this asnwer](http://stackoverflow.com/a/6039163/1461424).
- 再来看,你是对的.我认为你的意思是它只抛出异常,但没有改变代码的工作方式(比如改变`this`).现在我看到你指的是调用其他功能.
- 在某些情况下,八进制是有用的.它的C语法是可怕的,但我希望看到语言添加一个新的八进制语法,然后可以允许前零表单被弃用.当然,对于支持前导零形式的Javascript来说只是愚蠢.
我强烈建议每个开发人员现在开始使用严格模式.有足够的浏览器支持它,严格的模式将合法地帮助我们避免我们甚至不知道你的代码中的错误.
显然,在初始阶段,我们以前从未遇到过错误.为了获得全部好处,我们需要在切换到严格模式后进行适当的测试,以确保我们已经捕获了所有内容.当然,我们不只是抛弃use strict
我们的代码并假设没有错误.所以,流失是时候开始使用这个非常有用的语言功能来编写更好的代码.
例如,
var person = {
name : 'xyz',
position : 'abc',
fullname : function () { "use strict"; return this.name; }
};
JSLint是Douglas Crockford编写的调试器.只需粘贴您的脚本,它就会快速扫描代码中的任何明显问题和错误.
- @JamieHutber:请访问此链接http://caniuse.com/use-strict和http://kangax.github.io/es5-compat-table/.它将为所有浏览器提供准确的想法.
我想提供一个更有根据的答案,补充其他答案.我希望编辑最流行的答案,但失败了.我试图让它尽可能全面和完整.
您可以参考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
在严格模式下使用-statement. - 在严格模式下,必须声明所有变量:如果为尚未声明为变量,函数,函数参数,catch-clause参数或全局属性的标识符赋值
Object
,那么您将得到一个ReferenceError
.在正常模式下,标识符被隐式声明为全局变量(作为全局变量的属性Object
) - 在严格模式下,关键字
this
具有undefined
作为函数(而不是方法)调用的函数中的值.(在正常模式下this
始终指向全局Object
).这种差异可用于测试实现是否支持严格模式:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
- 在严格模式下,将代码传递给时
eval()
,您无法在调用者的范围内声明或定义变量或函数(正如您可以在正常模式下执行).而是创建一个新的范围eval()
,变量和函数在该范围内.eval()
完成执行后,该范围将被销毁. - 在严格模式下,函数的arguments-object包含值的静态副本,这些副本将传递给该函数.在正常模式下,arguments-object有一些"神奇"的行为:数组的元素和命名的函数参数都引用相同的值.
- 在严格模式下,你会得到一个
SyntaxError
当delete
操作者随后的非限定的标识符(变量,函数或函数参数).在正常模式下,delete
表达式将不执行任何操作并进行求值false
. - 在严格模式下,
TypeError
当您尝试删除不可配置的属性时,您将获得一个.(在正常模式下,尝试只是失败并且delete
表达式被评估为false
). - 在严格模式下,当您尝试为对象文字定义具有相同名称的多个属性时,会将其视为语法错误.(在正常模式下没有错误.)
- 在严格模式下,当函数声明具有多个具有相同名称的参数时,它被认为是语法错误.(在正常模式下没有错误.)
- 在严格模式下,不允许八进制文字(这些是以文字开头的文字
0x
.(在正常模式下,某些实现允许八进制文字.) - 在严格模式标识符
eval
和arguments
被当作关键字.您不能更改它们的值,不能为它们赋值,也不能将它们用作变量,函数,函数参数或catch块标识符的名称. - 在严格模式下,对检查调用堆栈的可能性有更多限制.
arguments.caller
并在严格模式下arguments.callee
导致TypeError
函数.此外,严格模式下函数的某些调用者和参数属性会TypeError
在您尝试读取它们时产生.
- "在严格模式下,不允许八进制文字(这些是以0x开头的文字......)"八进制文字以前导'0'开头.
我的两分钱:
严格模式的目标之一是允许更快地调试问题.它可以帮助开发人员在发生某些可能导致网页无声和奇怪行为的错误事件时抛出异常.在我们使用的那一刻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
代码时会抛出错误.
Sample
消除with
声明:
with
使用像uglify-js这样的工具不能缩小语句.它们也被弃用,并从未来的JavaScript版本中删除.
Sample
防止重复:
当我们有重复属性时,它会抛出异常
"use strict";
var tree1Data = {
name: 'Banana Tree',
age: 100,
leafCount: 100000,
name:'Banana Tree'
};
还有更多,但我需要获得更多的知识.
如果您使用过去一年左右发布的浏览器,那么它很可能支持JavaScript Strict模式.只有在ECMAScript 5成为当前标准之前的旧浏览器才支持它.
命令周围的引号确保代码仍然可以在旧版浏览器中工作(尽管在严格模式下生成语法错误的事情通常只会导致脚本在这些旧版浏览器中以某种难以检测的方式出现故障).
- 那它做了什么?
- ...这描述了_in part_兼容性,但不是它实际上做的.
添加时"use strict";
,以下情况将在脚本执行之前抛出SyntaxError:
-
if(a<b){ function f(){} }
-
var n = 023;
-
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();
-
"use strict"; arguments++; var obj = { set p(arguments) { } }; try { } catch (arguments) { } function arguments() { }
资料来源:
严格模式对常规JavaScript语义进行了一些更改:
了解更多信息vistit Strict Mode- Javascript
"使用严格"; 是程序员不会使用JavaScript的松散或不良属性的保险.这是一个指南,就像一个统治者将帮助你做直线."使用严格"将帮助您进行"直接编码".
那些不想使用统治者直接进行直线操作的人通常会在那些要求其他人调试代码的页面中结束.
相信我.与设计不良的代码相比,开销可以忽略不计.多年来一直担任高级JavaScript开发人员的Doug Crockford在这里发表了一篇非常有趣的帖子.就个人而言,我喜欢一直回到他的网站,以确保我不忘记我的良好做法.
现代JavaScript实践应该总是唤起"使用严格"; 附注.ECMA集团选择"严格"模式的唯一原因是允许经验较少的编码人员访问JavaScript,然后有时间适应新的更安全的编码实践.
- 严格模式是可选的原因与您所述的内容无关.真正的原因*是不破坏可能不符合*的现有代码.
- 实际上,经验较少的编码员应该是第一个能够"严格使用"的编码员.
use strict
从这一点开始包括所有敏感JavaScript文件的开头是一个很好的方法,可以成为一个更好的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"
在ECMA6中广泛需要使用它,在ECMA6中它默认是JavaScript的一部分,所以如果你使用ES6则不需要添加它.
查看MDN的这些陈述和示例:
使用"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上阅读更多内容.
一些参与ECMAScript委员会的人有一个很好的谈话:JavaScript的变化,第1部分:ECMAScript 5"关于"use strict"
交换机的增量使用如何允许JavaScript实施者清理JavaScript的许多危险特性而不会突然破坏每个网站在世界上.
当然,它还讨论了很多这些错误信息是什么以及ECMAScript 5如何修复它们.
要比较的小例子:
非严格模式:
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
- 请注意,上面的代码会将**i**变量添加到全局范围(通常这不是最佳实践,**严格模式**有助于避免这种情况).
请注意,这use strict
是在EcmaScript 5中引入的,从那时起就保存了下来.
以下是在ES6和ES7中触发严格模式的条件:
- 全局代码是严格模式代码,如果它以包含使用严格指令的指令序言开头(见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.
开发人员应该使用的主要原因"use strict"
是:
-
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"
指令仅在脚本或函数的开头被识别. -
"use strict"; var arguments = 3.14; // This will cause an error
简而言之,这将使您的代码不易出错,反过来会让您编写好的代码.
要了解更多信息,请参阅此处.
"严格使用"; 是ECMA努力使JavaScript更加强大.它引入了JS,试图使其至少有一点"严格"(其他语言自90年代起实施严格的规则).它实际上"迫使"JavaScript开发人员遵循某种编码最佳实践.JavaScript仍然非常脆弱.没有类型化变量,类型化方法等.我强烈建议JavaScript开发人员学习更强大的语言,如Java或ActionScript3,并在JavaScript代码中实现相同的最佳实践,它将更好地工作并且更容易调试.
ECMAScript 5中引入了JavaScript"严格"模式.
(function() {
"use strict";
your code...
})();
"use strict";
在JS文件的最顶层写入会打开严格的语法检查.它为我们完成以下任务:
use strict
也适用于个别功能.包含use strict
在代码中总是更好的做法.
浏览器兼容性问题:"use"指令旨在向后兼容.不支持它们的浏览器只会看到一个未被进一步引用的字符串文字.所以,他们会过去并继续前进.
use strict
是一种让你的代码更安全的方法,因为你不能使用危险的功能,这些功能可能不会像你期望的那样工作.并且在它使代码更加严格之前就被写了.
使用Strict用于显示常见错误和重复错误,以便以不同方式处理,并更改java脚本运行的方式,此类更改包括:
您还可以阅读这篇文章了解详情
通常,JavaScript不遵循严格的规则,因此增加了错误的可能性.使用之后"use strict"
,JavaScript代码应遵循严格的规则集,如在其他编程语言中使用,例如终止符的使用,初始化之前的声明等.
如果"use strict"
使用,则应遵循严格的规则集编写代码,从而减少错误和模糊的可能性.
“使用严格”;定义JavaScript代码应在“严格模式”下执行。
- “严格使用”指令是ECMAScript版本5中的新增功能。
- 它不是语句,而是文字表达式,被早期JavaScript版本忽略。
- “使用严格”的目的是指示应在“严格模式”下执行代码。
- 在严格模式下,例如,您不能使用未声明的变量。
除Internet Explorer 9及更低版本外,所有现代浏览器均支持“严格使用” 。
坏处
如果开发人员使用的是严格模式下的库,但开发人员习惯于在正常模式下工作,则他们可能会对该库调用某些无法按预期方式执行的操作。
更糟糕的是,由于开发人员处于正常模式,因此他们没有抛出额外错误的优点,因此错误可能会静默地失败。
另外,如上所述,严格模式会阻止您执行某些操作。
人们通常认为您不应该一开始就使用这些东西,但是一些开发人员不喜欢这种约束,而是想要使用该语言的所有功能。
-
https://www.tutorialsteacher.com/javascript/javascript-strict