最近,我通过Crockford的JSLint运行了一些JavaScript代码,并给出了以下错误: 第1行字符1处的问题:缺少“使用严格”语句。 进行搜索后,我发现有些人添加了“ use strict”;纳入他们的JavaScript代码。添加语句后,错误停止出现。不幸的是,谷歌没有透露此字符串语句背后的许多历史。当然,它一定与浏览器如何解释JavaScript有关,但是我不知道会有什么影响。 那么什么是“严格使用”?所有这些,这意味着什么,并且它仍然有意义吗? 当前的浏览器是否响应“严格使用”;字符串还是将来使用?
这篇关于Javascript严格模式的文章可能会让您感兴趣:John Resig-ECMAScript 5严格模式,JSON等 引用一些有趣的部分: 严格模式是ECMAScript 5中的一项新功能,可让您将程序或功能置于“严格”的操作环境中。这种严格的上下文会阻止采取某些措施,并引发更多异常。 和: 严格模式可以通过以下两种方式提供帮助: 它捕获了一些常见的编码漏洞,并引发异常。 当采取相对“不安全”的操作(例如获得对全局对象的访问权限)时,它可以防止或引发错误。 它禁用令人困惑或考虑不周的功能。 还要注意,您可以将“严格模式”应用于整个文件...或者您可以将其仅用于特定功能(仍引用John Resig的文章): //非严格代码... (功能(){ “使用严格”; //严格定义您的库... })(); //非严格代码... 如果您必须混合使用旧代码和新代码,这可能会有所帮助;-) 因此,我想这有点像您可以在Perl中使用“严格使用”(因此得名?):它通过检测更多可能导致损坏的内容来帮助您减少错误。 所有主要浏览器现在都支持严格模式。 在本机ECMAScript模块(带有导入和导出语句)和ES6类中,严格模式始终处于启用状态,不能被禁用。 | 这是ECMAScript 5的新功能。JohnResig对此进行了很好的总结。 这只是您放入JavaScript文件(位于文件顶部或函数内部)的字符串,如下所示: “使用严格”; 现在将其放入您的代码中应该不会对当前的浏览器造成任何问题,因为它只是一个字符串。如果您的代码违反了编译指示,将来可能会导致您的代码出现问题。例如,如果您当前具有foo =“ bar”而不首先定义foo,则您的代码将开始失败...在我看来,这是一件好事。 | 声明“使用严格”;指示浏览器使用严格模式,这是JavaScript的简化和安全功能集。 功能列表(非穷举) 禁止使用全局变量。 (捕获变量名称中缺少的var声明和错别字) 静默失败的分配将在严格模式下引发错误(分配NaN = 5;) 尝试删除不可删除的属性将引发(删除Object.prototype) 要求对象文字中的所有属性名称必须唯一(var x = {x1:“ 1”,x1:“ 2”}) 函数参数名称必须唯一(函数总和(x,x){...}) 禁止使用八进制语法(var x = 023;某些开发人员错误地认为前面的零不会更改数字。) 禁止with关键字 严格模式下的eval不会引入新变量 禁止删除纯名称(删除x;) 禁止以任何形式绑定或分配名称eval和参数 严格模式不会将参数对象的属性与形式参数混用。 (即函数sum(a,b){return arguments [0] + b;}之所以有效,是因为arguments [0]绑定到a上,依此类推。) 不支持arguments.callee [参考:严格模式,Mozilla开发人员网络] | 如果人们担心使用严格的使用,那么可能值得阅读这篇文章: 浏览器中的ECMAScript 5“严格模式”支持。这是什么意思?NovoGeek.com-克里希纳的博客 它讨论了浏览器支持,但更重要的是如何安全地处理它: 函数isStrictMode(){ 返回! } / * 返回false,因为'this'指向全局对象,并且 '!这'变成假 * / 函数isStrictMode(){ “使用严格”; 返回! } / * 返回true,因为在严格模式下,关键字“ this” 与传统的JS不同,它不引用全局对象。 因此,这里的“ this”是“ undefined”,“!this”变为true。 * / | 提醒您,所有苛刻的程序员:对现有代码应用“严格使用”可能很危险!这东西不是一些让人感觉愉悦,表情愉悦的标签,您可以在代码上拍一下以使其“更好”。使用“严格使用”杂语,浏览器会突然在从未发生过的随机位置抛出异常,这仅仅是因为您正在执行默认/宽松JavaScript允许但严格JavaScript讨厌的事情!您可能会遇到严格的违规情况,这些隐瞒了您的代码中很少使用的调用,这些调用只会在最终运行时才会引发异常-例如,在付费客户使用的生产环境中! 如果您要尝试一下,最好将“使用严格”与全面的单元测试以及严格配置的JSHint构建任务一起应用,这将使您充满信心,您的模块不会出现死角可怕的是,因为您已启用严格模式。或者,嘿,这是另一个选择:就是不要在您的任何旧代码中添加“ use strict”,老实说,这样做可能更安全。绝对不要在您不拥有或未拥有的任何模块中添加“使用严格”像第三方模块一样进行维护。 我认为,即使这是一种致命的笼养动物,“严格使用”也可能是好东西,但您必须正确地做。严格执行的最佳时间是当您的项目处于未开发状态并且从头开始时。在JSHint / JSLint上配置所有警告和选项,使您的团队可以紧紧抓住,并在诸如Grunt + Karma + Chai之类的操纵下获得良好的构建/测试/声明系统,然后只有THEN才开始将所有新模块标记为“使用严格”。准备好解决许多小错误和警告。如果JSHint / JSLint产生任何违规,请通过将构建配置为FAIL来确保每个人都了解重力。 当我采用“使用严格”时,我的项目不是一个新项目。结果,我的IDE充满了红色标记,因为我对模块的一半没有“严格使用”,而JSHint对此表示抱怨。这让我想起了将来应该做的重构。我的目标是消除我所有的“使用严格”声明,以免出现红标,但距离现在还很遥远。 | 使用“严格使用”;不会突然使您的代码变得更好。 JavaScript严格模式是ECMAScript 5中的功能。您可以通过在脚本/函数顶部进行声明来启用严格模式。 “使用严格”; 当JavaScript引擎看到此指令时,它将开始以特殊模式解释代码。在这种模式下,当检测到某些可能最终成为潜在错误的编码实践时,就会引发错误(这是严格模式下的原因)。 考虑以下示例: var a = 365; var b = 030; 为了吸引数字文字,开发人员在不经意间将变量b初始化为八进制文字。非严格模式会将其解释为带有值24(以10为底)的数字文字。但是,严格模式将引发错误。 有关严格模式下的专业的详尽列表,请参见此答案。 我应该在哪里使用“严格使用”;? 在我的新JavaScript应用程序中:绝对!当您对代码进行愚蠢的操作时,严格模式可以用作举报者。 在我现有的JavaScript代码中:可能不是!如果您现有的JavaScript代码包含在严格模式下被禁止的语句,则应用程序将很容易崩溃。如果要使用严格模式,则应该准备调试和更正现有代码。这就是为什么使用“严格使用”的原因;不会突然使您的代码变得更好。 如何使用严格模式? 插入“使用严格”;脚本顶部的语句: //文件:myscript.js “使用严格”; var a = 2; .... 请注意,文件myscript.js中的所有内容都将以严格模式进行解释。 或者,插入“使用严格”;在函数主体顶部的语句: 函数doSomething(){ “使用严格”; ... } 函数doSomething的词法范围内的所有内容都将以严格模式进行解释。词汇范围一词在这里很重要。例如,如果您的严格代码调用了非严格库的函数,则仅您的代码以严格模式执行,而不是被调用函数。请参阅此答案以获得更好的解释。 严格模式下禁止哪些事情? 我找到了一篇不错的文章,描述了严格模式下禁止的几件事(请注意,这不是排他性清单): 范围 从历史上看,JavaScript对于功能如何一直感到困惑 范围。有时它们似乎是静态作用域,但有些 功能使它们的行为就像动态范围一样。这是 令人困惑,使程序难以阅读和理解。 误会导致错误。这也是性能问题。 静态作用域将允许在编译时进行变量绑定 时间,但是对动态范围的要求意味着绑定必须是 推迟到运行时,这具有显着的性能 罚款。 严格模式要求所有变量绑定都是静态完成的。 这意味着以前需要动态绑定的功能 必须消除或修改。具体来说,with语句是 消除,并且评估功能可以篡改 呼叫者的环境受到严格限制。 严格代码的好处之一是像YUI Compressor这样的工具 在处理它时可以做得更好。 隐含全局变量 JavaScript隐含了全局变量。如果 您没有显式声明变量,而是全局变量 为您隐式声明。这使得编程更容易 初学者,因为他们可以忽略一些基本的家务管理 琐事。但这使大型程序的管理更多 困难,并且大大降低了可靠性。所以严格 模式下,不再创建隐式全局变量。你应该 显式声明所有变量。 全球泄漏 在多种情况下可能会导致这种情况 绑定到全局对象。例如,如果您忘记 在调用构造函数时提供新的前缀功能, 构造函数的this会意外绑定到全局对象,因此 与其初始化一个新对象,不如说它是静默的 篡改全局变量。在这些情况下,严格模式将 而是将其绑定到undefined,这将导致构造函数 而是引发异常,从而使错误可以被大量检测 早点 嘈杂的失败 JavaScript一直具有只读属性,但是您 在ES5的Object.createProperty之前无法自己创建它们 功能暴露了这种能力。如果您尝试分配一个值 只读属性,它将无提示地失败。作业将 不会更改属性的值,但是您的程序将继续执行 虽然有。这是完整性危害,可能导致程序无法 进入不一致状态。在严格模式下,尝试更改 只读属性将引发异常。 八进制 数字的八进制(或以8为底)表示非常 在其单词的机器上进行机器级编程时很有用 大小是3的倍数。使用CDC时需要八进制 6600大型机,字长为60位。如果你能读 八进制,您可以将单词看成20位数字。代表两位数 操作码和一位数字标识8个寄存器之一。在此期间 从机器代码到高级语言的缓慢转换 被认为对以编程语言提供八进制形式很有用。 在C语言中,八进制的一种极其不幸的表示是 已选择:前导零。因此,在C中,0100表示64,而不是100,而08是 错误,而不是8。更不幸的是,这种不合时宜的原因是 复制到几乎所有现代语言(包括JavaScript)中, 它仅用于创建错误。它没有其他目的。所以在 严格模式下,不再允许使用八进制形式。 等等 参数伪数组变得更多 在ES5中类似于数组。在严格模式下,它将丢失被叫方和呼叫方 属性。这样就可以将您的论点传递给不受信任的对象 无需放弃很多机密上下文的代码。另外, 函数的arguments属性被消除。 在严格模式下,函数文字中的重复键将产生一个 语法错误。一个函数不能有两个具有相同名称的参数。 函数不能具有与其名称之一相同的变量 参数。函数不能删除自己的变量。试图 删除一个不可配置的属性现在会引发异常。原始 值不是隐式包装的。 将来的JavaScript版本的保留字 ECMAScript 5添加了保留字列表。如果将它们用作变量或参数,则严格模式将引发错误。保留字为: 实现,接口,让,打包,私有,受保护,公共,静态和yield 进一步阅读 严格模式-JavaScript | MDN 浏览器对严格模式的支持 过渡到严格模式 | 我强烈建议每个开发人员立即开始使用严格模式。有足够多的浏览器支持它,严格模式可以合理地帮助我们避免代码中甚至不知道的错误。 显然,在初始阶段会有一些我们从未遇到过的错误。为了获得全部收益,我们需要在切换到严格模式后进行适当的测试,以确保我们已捕获所有内容。绝对我们不只是在代码中使用严格,并假设没有错误。因此,令人感到奇怪的是,是时候开始使用这一非常有用的语言功能编写更好的代码了。 例如, var person = { 名称:'xyz', 位置:“ abc”, fullname:function(){“使用严格”;返回this.name; } }; JSLint是由Douglas Crockford编写的调试器。只需粘贴您的脚本,它就会快速扫描代码中任何明显的问题和错误。 | 我想提供一个更有根据的答案来补充其他答案。我希望编辑最流行的答案,但失败了。我试图使它尽可能全面和完整。 您可以参考MDN文档以获取更多信息。 “严格使用”是ECMAScript 5中引入的指令。 指令与语句相似,但有所不同。 use strict不包含关键字:该指令是一个简单的表达式语句,由特殊的字符串文字(单引号或双引号)组成。没有实现ECMAScript 5的JavaScript引擎只能看到一个没有副作用的表达式语句。预计将来的ECMAScript标准版本会引入使用作为真正的关键词;这样一来,报价就会过时。 use strict只能在脚本或函数的开头使用,即必须在所有其他(真实)语句之前。它不一定是函数脚本中的第一条指令:它可以在其他由字符串文字(和JavaScript)组成的语句表达式之前实现可以将它们视为实现特定的指令)。紧跟在脚本或函数中的第一个实数语句之后的字符串文字语句是简单的表达式语句。口译员不得将其解释为指令,并且它们无效。 use strict指令指示以下代码(在脚本或函数中)是严格代码。 当脚本包含使用严格指令时,脚本最高级别的代码(不在函数中的代码)被视为严格代码。 当函数本身在严格代码中定义或当函数包含use strict指令时,该函数的内容被视为严格代码。 当从严格代码调用eval()或包含use strict指令本身时,传递给eval()方法的代码被视为严格代码。 ECMAScript 5的严格模式是JavaScript语言的受限子集,它消除了该语言的相关缺陷,并具有更严格的错误检查和更高的安全性。下面列出了严格模式和普通模式之间的区别(前三个特别重要): 您不能在严格模式下使用with语句。 在严格模式下,必须声明所有变量:如果将一个值赋给尚未声明为全局对象的变量,函数,函数参数,子句参数或属性的标识符,则将收到ReferenceError。在正常模式下,标识符隐式声明为全局变量(作为全局对象的属性) 在严格模式下,关键字this的值在作为函数(而不是方法)调用的函数中具有未定义的值。 (在正常模式下,它始终指向全局对象)。此差异可用于测试实现是否支持严格模式: var hasStrictMode =(function(){“ use strict”;返回this === undefined}()); 同样,当使用call()调用函数或以严格模式应用函数时,这恰好是call()或apply()调用的第一个参数的值。 (在正常模式下,将null和undefined替换为全局Object,并将不是对象的值强制转换为对象。) 在严格模式下,当您尝试分配给只读属性或为不可扩展对象定义新属性时,将出现TypeError。 (在正常模式下,两者都只会失败而不会显示错误消息。) 在严格模式下,将代码传递给eval()时,不能在调用方的范围内声明或定义变量或函数(就像在常规模式下那样)。而是为eval()创建一个新范围,并且变量和函数都在该范围内。 eval()完成执行后,该作用域被销毁。 在严格模式下,函数的arguments对象包含值的静态副本,这些值将传递给该函数。在正常模式下,arguments-object的行为有些“神奇”:数组的元素和命名的函数参数都引用相同的值。 在严格模式下,当delete运算符后跟非限定标识符(变量,函数或函数参数)时,将出现SyntaxError。在正常模式下,delete表达式将不执行任何操作,并被评估为false。 在严格模式下,当您尝试删除不可配置的属性时,将出现TypeError。 (在正常模式下,尝试仅会失败,并且delete表达式的计算结果为false)。 在严格模式下,当您尝试为对象文字定义相同名称的多个属性时,将其视为语法错误。 (在正常模式下没有错误。) 在严格模式下,当函数声明具有多个具有相同名称的参数时,将其视为语法错误。 (在正常模式下没有错误。) 在严格模式下,不允许使用八进制文字(这些文字以0x开头。(在正常模式下,某些实现确实允许使用八进制文字。) 在严格模式下,标识符eval和参数被视为关键字。您不能更改它们的值,不能给它们分配值,也不能将它们用作变量,函数,函数参数或catch块标识符的名称。 在严格模式下,对检查调用堆栈的可能性有更多限制。 arguments.caller和arguments.callee在严格模式下的函数中导致TypeError。此外,在严格模式下,函数的某些调用方和参数属性会在您尝试读取它们时导致TypeError。 | 我的两分钱: 严格模式的目标之一是允许更快地调试问题。当发生某些错误事件时,它会引发异常,从而导致您的网页无声或奇怪的行为,它可以通过引发异常来帮助开发人员。一旦我们使用严格,代码就会抛出错误,这有助于开发人员提前修复它。 在使用strict之后,我学到的一些重要的东西很少: 防止全局变量声明: var tree1Data= {名称:“香蕉树”,年龄:100,叶数:100000}; 函数Tree(typeOfTree){ var age; var leafCount; 年龄= typeOfTree.age; leafCount = typeOfTree.leafCount; nameoftree = typeOfTree.name; }; var tree1 = new Tree(tree1Data); console.log(window); 现在,此代码在全局范围内创建nameoftree,可以使用window.nameoftree进行访问。当我们执行严格使用时,代码将引发错误。 未捕获的ReferenceError:未定义nameoftree 样品 用语句消除: 使用uglify-js之类的工具无法最小化with语句。它们也已弃用,并从将来的JavaScript版本中删除。 样品 防止重复: 当我们有重复的属性时,它将引发异常 未捕获的SyntaxError:对象文字中的重复数据属性不正确 在严格模式下允许 “使用严格”; var tree1Data = { 名称:“香蕉树” 年龄:100岁 leafCount:100000, 名称:“香蕉树” }; 很少,但是我需要获得更多的知识。 | 如果您使用的是去年左右发布的浏览器,则该浏览器很可能支持JavaScript严格模式。只有在ECMAScript 5成为当前标准之前的较旧的浏览器才不支持它。 该命令周围的引号确保该代码在旧版本的浏览器中也仍然可以运行(尽管在严格模式下生成语法错误的内容通常只会导致脚本在旧版本的浏览器中以某种难以检测的方式发生故障)。 | 当添加“ use strict”;时,以下情况将在脚本执行之前引发SyntaxError: 使用新保留的关键字之一(在ECMAScript 6的预设中)为将来的ECMAScript版本铺平道路:实现,接口,让,打包,私有,受保护,公共,静态和yield。 块中声明功能 if(a :3:15) 在<匿名>:6:5 在这里,编译器将引发参考错误。在严格模式下,编译器不允许我们在未声明的情况下使用变量。因此可以防止内存泄漏。另外,我们可以编写更多优化的代码。 | 严格模式消除了在非严格模式下将被忽略的错误,从而使javascript“更加安全”。 是否被认为是最佳做法? 是的,在使用javascript纳入严格模式时,它被视为最佳做法的一部分。这是通过在您的JS文件中添加以下代码行来完成的。 “使用严格”; 在您的代码中。 对用户代理意味着什么? 表示应该以严格模式解释代码,这会向浏览器之类的用户代理指定用户应按字面意义对待代码,如果代码没有意义,则会抛出错误。 例如:考虑在您的.js文件中,您具有以下代码: 方案1:[无限制模式] var city =“芝加哥” console.log(city)//打印城市名称,即芝加哥 方案2:[无限制模式] city =“芝加哥” console.log(city)//打印城市名称,即芝加哥 那么为什么在两种情况下都打印变量名呢? 如果未启用严格模式,则用户代理通常会对有问题的代码进行一系列修改,以使代码有意义。从表面上看,这似乎是一件好事,而且确实,在严格模式下工作使人们可以在不弄清所有细节的情况下使用JavaScript代码。但是,作为开发人员,我不想在代码中留下错误,因为我知道它可能会回来并在以后咬住我,我也只想编写出色的代码。这就是严格模式可以提供帮助的地方。 方案3:[严格模式] “使用严格”; city =“芝加哥” console.log(city)//参考错误:赋值是未声明的变量city。 附加提示:要使用严格模式保持代码质量,则无需一遍又一遍地编写代码,特别是如果您有多个.js文件。您可以在eslint规则中全局执行此规则,如下所示: 文件名:.eslintrc.js module.exports = { 信封:{ es6:是 }, 规则:{ 严格:['错误','全局'], }, }; 好吧,那么严格模式下可以防止什么呢? 在不声明变量的情况下使用变量将在严格模式下引发错误。这是为了防止在整个应用程序中无意间创建全局变量。印刷芝加哥的示例尤其涵盖了这一点。 在严格模式下,删除变量,函数或参数是不可以的。 “使用严格”; 函数x(p1,p2){}; 删除x; //这会导致错误 在严格模式下,不允许重复参数名称。 “使用严格”; 函数x(p1,p1){}; //这会导致错误 严格模式下不允许使用Java语言的保留字。这些词是工具接口,让,包,私有,受保护,公开。静态和屈服 有关更全面的列表,请查看以下MDN文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode | 高度活跃的问题。赢得10个声誉才能回答这个问题。信誉要求有助于保护该问题免受垃圾邮件和非答复活动的侵害。 不是您要找的答案?浏览标记为javascript语法jslint use-strict的其他问题,或提出您自己的问题。