What does “use strict” do in JavaScript, and what is the reasoning behind it?
最近,我通过Crockford的JSlint运行了一些javascript代码,它给出了以下错误:
Problem at line 1 character 1: Missing"use strict" statement.
在进行一些搜索时,我发现有些人在他们的javascript代码中添加了
那么,
当前的浏览器有没有响应
这篇关于javascript严格模式的文章可能会让您感兴趣:john resig-ecmascript 5严格模式、json等等
引用一些有趣的部分:
Strict Mode is a new feature in ECMAScript 5 that allows you to place a program, or a function, in a"strict" operating context. This strict context prevents certain actions from being taken and throws more exceptions.
还有:
Strict mode helps out in a couple ways:
- It catches some common coding bloopers, throwing exceptions.
- It prevents, or throws errors, when relatively"unsafe" actions are taken (such as gaining access to the global object).
- It disables features that are confusing or poorly thought out.
另外请注意,您可以对整个文件应用"严格模式"…或者您只能将其用于特定的函数(仍然引用John Resig的文章):
1
2
3
4
5
6
7
8
9 // Non-strict code...
(function(){
"use strict";
// Define your library strictly...
})();
// Non-strict code...
如果必须混合新旧代码,这可能会有所帮助;-)
所以,我想这有点像
目前,所有主要的浏览器都支持它(Ie9及以下)。
这是ECMAScript 5的一个新特性。约翰·雷西格写了一个很好的总结。
它只是您放入JavaScript文件(文件顶部或函数内部)中的字符串,如下所示:
1 | "use strict"; |
现在将它放入代码中不会对当前的浏览器造成任何问题,因为它只是一个字符串。如果您的代码违反了pragma,将来可能会导致代码出现问题。例如,如果您当前有
语句
不允许全局变量。(捕获缺少的
无提示失败分配将在严格模式下引发错误(分配
删除不可删除属性的尝试将引发(
要求对象文本中的所有属性名称都是唯一的( 如果人们担心使用 浏览器中支持ECMAScript 5"严格模式"。这是什么意思?Novogeek.com-Krishna的日志 它讨论了浏览器支持,但更重要的是如何安全地处理它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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. */ |
一句警告,所有的编程人员都很努力:将
如果您打算冒险,最好将
我认为即使它是一种致命的笼中动物,
当我采用
使用
Javascript Strict模式是EcmaScript 5中的一个功能。您可以通过在脚本/函数的顶部声明来启用严格模式。
1 | 'use strict'; |
当一个javascript引擎看到这个指令时,它将开始以一种特殊的模式解释代码。在这种模式下,当检测到某些可能最终成为潜在错误的编码实践时(这是严格模式背后的推理),就会引发错误。
考虑这个例子:
1 2 | var a = 365; var b = 030; |
在他们对排列数字字面值的痴迷中,开发人员无意中用八进制字面值初始化了变量
有关严格模式下的非详尽专业列表,请参阅此答案。
我应该在哪里使用在我的新javascript应用程序中:绝对!当你在用你的代码做一些愚蠢的事情时,严格模式可以被用作告密者。
在我现有的javascript代码中:可能不是!如果您现有的javascript代码中有严格模式下禁止的语句,应用程序将简单地中断。如果需要严格模式,则应准备调试和更正现有代码。这就是为什么使用
'use strict'; 不会突然使代码变得更好。
如何使用严格模式?
在脚本顶部插入一个
1 2 3 4 5 | // File: myscript.js 'use strict'; var a = 2; .... |
请注意,文件
或者,在您的函数体顶部插入一个
1 2 3 4 | function doSomething() { 'use strict'; ... } |
函数
什么东西是严格禁止的?
我发现了一篇很好的文章,描述了在严格模式下禁止的一些事情(请注意,这不是一个排他列表):
Scope
Historically, JavaScript has been confused about how functions
are scoped. Sometimes they seem to be statically scoped, but some
features make them behave like they are dynamically scoped. This is
confusing, making programs difficult to read and understand.
Misunderstanding causes bugs. It also is a problem for performance.
Static scoping would permit variable binding to happen at compile
time, but the requirement for dynamic scope means the binding must be
deferred to runtime, which comes with a significant performance
penalty.Strict mode requires that all variable binding be done statically.
That means that the features that previously required dynamic binding
must be eliminated or modified. Specifically, the with statement is
eliminated, and the eval function’s ability to tamper with the
environment of its caller is severely restricted.One of the benefits of strict code is that tools like YUI Compressor
can do a better job when processing it.Implied Global Variables
JavaScript has implied global variables. If
you do not explicitly declare a variable, a global variable is
implicitly declared for you. This makes programming easier for
beginners because they can neglect some of their basic housekeeping
chores. But it makes the management of larger programs much more
difficult and it significantly degrades reliability. So in strict
mode, implied global variables are no longer created. You should
explicitly declare all of your variables.Global Leakage
There are a number of situations that could cause
this
to be bound to the global object. For example, if you forget to
provide thenew prefix when calling a constructor function, the
constructor'sthis will be bound unexpectedly to the global object, so
instead of initializing a new object, it will instead be silently
tampering with global variables. In these situations, strict mode will
instead bindthis toundefined , which will cause the constructor to
throw an exception instead, allowing the error to be detected much
sooner.Noisy Failure
JavaScript has always had read-only properties, but you
could not create them yourself until ES5’sObject.createProperty
function exposed that capability. If you attempted to assign a value
to a read-only property, it would fail silently. The assignment would
not change the property’s value, but your program would proceed as
though it had. This is an integrity hazard that can cause programs to
go into an inconsistent state. In strict mode, attempting to change a
read-only property will throw an exception.Octal
The octal (or base 8) representation of numbers was extremely
useful when doing machine-level programming on machines whose word
sizes were a multiple of 3. You needed octal when working with the CDC
6600 mainframe, which had a word size of 60 bits. If you could read
octal, you could look at a word as 20 digits. Two digits represented
the op code, and one digit identified one of 8 registers. During the
slow transition from machine codes to high level languages, it was
thought to be useful to provide octal forms in programming languages.In C, an extremely unfortunate representation of octalness was
selected: Leading zero. So in C,0100 means 64, not 100, and08 is an
error, not 8. Even more unfortunately, this anachronism has been
copied into nearly all modern languages, including JavaScript, where
it is only used to create errors. It has no other purpose. So in
strict mode, octal forms are no longer allowed.Et cetera
The arguments pseudo array becomes a little bit more
array-like in ES5. In strict mode, it loses itscallee andcaller
properties. This makes it possible to pass yourarguments to untrusted
code without giving up a lot of confidential context. Also, the
arguments property of functions is eliminated.In strict mode, duplicate keys in a function literal will produce a
syntax error. A function can’t have two parameters with the same name.
A function can’t have a variable with the same name as one of its
parameters. A function can’tdelete its own variables. An attempt to
delete a non-configurable property now throws an exception. Primitive
values are not implicitly wrapped.
为将来的javascript版本保留字
ECMAScript 5添加了保留字列表。如果将它们用作变量或参数,则严格模式将引发错误。保留字为:
implements ,interface ,let ,package ,private ,protected ,public ,static , andyield
进一步阅读
- 严格模式-javascript mdn
- 严格模式的浏览器支持
- 过渡到严格模式
我强烈建议每个开发人员现在就开始使用严格模式。有足够的浏览器支持它,严格的模式将合法地帮助我们避免我们甚至不知道在您的代码中的错误。
显然,在最初阶段,我们将遇到以前从未遇到过的错误。为了获得最大的好处,我们需要在切换到严格模式后进行适当的测试,以确保我们捕获了所有的东西。当然,我们不只是在代码中抛出
例如,
1 2 3 4 5 | var person = { name : 'xyz', position : 'abc', fullname : function () { "use strict"; return this.name; } }; |
JSlint是道格拉斯·克罗克福德(DouglasCrockford)编写的一个调试器。只需粘贴到脚本中,它就可以快速扫描代码中任何明显的问题和错误。
我想提供一个更有根据的答案来补充其他答案。我本想编辑最受欢迎的答案,但失败了。我努力使它尽可能的全面和完整。好的。
有关详细信息,请参阅MDN文档。好的。
指令与语句相似,但不同。好的。
use strict 不包含关键字:该指令是一个简单的表达式语句,它由一个特殊的字符串文本(单引号或双引号)组成。不实现ECMAScript 5的JavaScript引擎只看到一个没有副作用的表达式语句。预计未来版本的ecmascript标准将引入use 作为一个真正的关键词;因此,引用将变得过时。use strict 只能在脚本或函数的开头使用,即它必须位于其他(real)语句之前。它不必是函数脚本中的第一条指令:它前面可以是由字符串文本组成的其他语句表达式(JavaScript实现可以将它们视为实现特定的指令)。字符串文本语句(在脚本或函数中)位于第一个实数语句之后,是简单的表达式语句。口译员不得将其解释为指令,且不具有任何效力。
ECMAScript 5的严格模式是JavaScript语言的一个子集,它消除了语言的相关缺陷,具有更严格的错误检查和更高的安全性。下面列出了严格模式和正常模式(前三种模式尤为重要)之间的区别:好的。
- 不能在严格模式下使用
with 语句。 - 在严格模式下,所有变量都必须声明:如果您将一个值赋给一个未声明为全局
Object 的变量、函数、函数参数、catch子句参数或属性的标识符,那么您将得到一个ReferenceError 。在正常模式下,标识符隐式声明为全局变量(作为全局Object 的属性) - 在严格模式下,关键字
this 在作为函数(而不是作为方法)调用的函数中具有值undefined 。(在正常模式下,this 始终指向全局Object )。此差异可用于测试实现是否支持严格模式:
1 var hasStrictMode = (function() {"use strict"; return this===undefined }());
同样,当一个函数在严格模式下用
call() 或apply 调用时,那么this 正是call() 或apply() 调用的第一个参数的值。(在正常模式下,null 和undefined 被全局Object 替换,而不是对象的值被转换为对象。)好的。在严格模式下,当您试图分配给只读属性或为不可扩展对象定义新属性时,您将得到一个
TypeError 。(在正常模式下,两者都会失败,不会出现错误信息。)好的。- 在严格模式下,当向
eval() 传递代码时,不能在调用方的范围内声明或定义变量或函数(在正常模式下可以这样做)。相反,为eval() 创建了一个新的作用域,变量和函数都在这个作用域内。该范围在eval() 完成执行后被销毁。 - 在严格模式下,函数的arguments对象包含传递给该函数的值的静态副本。在正常模式下,arguments对象具有某种"神奇"的行为:数组元素和命名函数参数都引用相同的值。
- 在严格模式下,当
delete 运算符后面跟一个非限定标识符(变量、函数或函数参数)时,您将得到一个SyntaxError 。在正常模式下,delete 的表达不起作用,并被评估为false 。 - 在严格模式下,当您试图删除一个不可配置的属性时,您将得到一个
TypeError 。(在正常模式下,尝试失败,delete 表达被评估为false 。 - 在严格模式下,当您试图为一个对象文本定义多个具有相同名称的属性时,它被认为是一个语法错误。(在正常模式下没有错误。)
- 在严格模式下,当一个函数声明有多个同名参数时,它被认为是语法错误。(在正常模式下没有错误。)
- 在严格模式下,不允许使用八进制文字(这些文字以
0x 开头)。(在正常模式下,某些实现允许使用八进制文字。) - 在严格模式下,标识符
eval 和arguments 被视为关键字。不能更改它们的值,不能为它们赋值,也不能将它们用作catch块的变量、函数、函数参数或标识符的名称。 - 在严格模式下,对检查调用堆栈的可能性有更多的限制。
arguments.caller 和arguments.callee 导致TypeError 在严格模式下的函数中。此外,在严格模式下函数的一些调用者和参数属性在您试图读取它们时会导致TypeError 。
好啊。
我的两分钱:
严格模式的目标之一是允许更快地调试问题。它可以帮助开发人员在某些错误的事情发生时抛出异常,这些错误会导致网页的无声和奇怪行为。当我们使用
在使用
阻止全局变量声明:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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); |
现在,该代码在全局范围内创建
Uncaught ReferenceError: nameoftree is not defined
S电流断路器
删除
不能使用uglify JS等工具缩小
S电流断路器
防止重复:
当我们有重复的属性时,它抛出一个异常
Uncaught SyntaxError: Duplicate data property in object literal not
allowed in strict mode
1 2 3 4 5 6 7 | "use strict"; var tree1Data = { name: 'Banana Tree', age: 100, leafCount: 100000, name:'Banana Tree' }; |
还有一些,但我需要更多的知识。
如果您使用的是去年左右发布的浏览器,那么它很可能支持JavaScript严格模式。只有在EcmaScript5成为当前标准之前的老版本浏览器才不支持它。
命令周围的引号确保代码在旧的浏览器中仍然有效(尽管在严格模式下生成语法错误的内容通常只会导致脚本在旧的浏览器中以某种难以检测的方式出现故障)。
在添加
为将来的ecmascript版本铺平道路,使用新保留的关键字之一(在ecmascript 6的预防中):
implements 、interface 、let 、package 、private 、protected 、public 、static 和yield 。在块中声明函数
1if(a<b){ function f(){} }八进制语法
1var n = 023;this 指向全局对象。1
2
3
4
5function f() {
"use strict";
this.a = 1;
};
f();在对象文本中为属性名声明两次相同的名称
1{a: 1, b: 3, a: 7}ECMAScript 6不再是这种情况(bug 1041128)。
用相同名称的函数声明两个函数参数
1f(a, b, b){}将值设置为未声明的变量
1
2
3
4
5
6function f(x){
"use strict";
var a = 12;
b = a + x*35; // error!
}
f();在变量名
delete myVariable; 上使用delete 。使用
eval 或arguments 作为变量或函数参数名1
2
3
4
5"use strict";
arguments++;
var obj = { set p(arguments) { } };
try { } catch (arguments) { }
function arguments() { }
资料来源:
在MDN上转换为严格模式
MDN上的严格模式
Javascript的严格模式以及为什么要在ColinJ.IHrig的博客上使用它(存档版本)
严格模式对正常的javascript语义进行了几次更改:
通过更改来消除一些javascript静默错误抛出错误。
修复使JavaScript变得困难的错误执行优化的引擎。
禁止将来可能定义的某些语法ECMAScript的版本。
有关更多信息,请访问严格模式-javascript
"use strict"是一种保证,程序员不会使用javascript的松散或不好的属性。它是一个向导,就像尺子可以帮助你画直线一样。"使用严格的"将帮助您做"直接编码。
那些不喜欢用尺子把它们的行笔直地画出来的人通常会在那些要求其他人调试代码的页面中结束。
相信我。与设计糟糕的代码相比,开销可以忽略不计。DougCrockford多年来一直是高级JavaScript开发人员,他在这里有一篇非常有趣的文章。就我个人而言,我喜欢随时返回他的网站,以确保我不会忘记我的良好实践。
现代的JavaScript实践应该总是唤起"使用严格的";语用。ECMA小组之所以选择"严格"模式,唯一的原因是允许经验不足的编码人员访问JavaScript,并给他们时间来适应新的、更安全的编码实践。
从这一点来看,在所有敏感的javascript文件的开头包括
W3学校报价:
The"use strict" Directive
The"use strict" directive is new in JavaScript 1.8.5 (ECMAScript
version 5).It is not a statement, but a literal expression, ignored by earlier
versions of JavaScript.The purpose of"use strict" is to indicate that the code should be
executed in"strict mode".With strict mode, you can not, for example, use undeclared variables.
Why Strict Mode?
Strict mode makes it easier to write"secure" JavaScript.
Strict mode changes previously accepted"bad syntax" into real errors.
As an example, in normal JavaScript, mistyping a variable name creates
a new global variable. In strict mode, this will throw an error,
making it impossible to accidentally create a global variable.In normal JavaScript, a developer will not receive any error feedback
assigning values to non-writable properties.In strict mode, any assignment to a non-writable property, a
getter-only property, a non-existing property, a non-existing
variable, or a non-existing object, will throw an error.
请访问http://www.w3schools.com/js/js-strict.asp了解更多信息
同样在严格模式下,运行速度更快,一些警告或无声警告会引发致命错误,最好始终使用它来生成更整洁的代码。
查看MDN中的这些语句和示例:
The"use strict" Directive The"use strict" directive is new in
JavaScript 1.8.5 (ECMAScript version 5). It is not a statement, but a
literal expression, ignored by earlier versions of JavaScript. The
purpose of"use strict" is to indicate that the code should be
executed in"strict mode". With strict mode, you can not, for example,
use undeclared variables.Examples of using"use strict":
Strict mode for functions: Likewise, to invoke strict mode for a
function, put the exact statement"use strict"; (or 'use strict';) in
the function's body before any other statements.
1)严格的功能模式
1 2 3 4 5 6 7 8 9 | 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)全脚本严格模式
1 2 3 | 'use strict'; var v ="Hi! I'm a strict mode script!"; console.log(v); |
3)分配给不可写全局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | '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"关于增量使用
当然,它也谈到了很多这样的错误,以及ECMAScript 5是如何修复它们的。
要比较的小示例:
非严格模式:
1 2 3 4 5 6 | for (i of [1,2,3]) console.log(i) // output: // 1 // 2 // 3 |
严格模式:
1 2 3 4 5 | 'use strict'; for (i of [1,2,3]) console.log(i) // output: // Uncaught ReferenceError: i is not defined |
非严格模式:
1 2 3 4 5 6 7 8 | String.prototype.test = function () { console.log(typeof this === 'string'); }; 'a'.test(); // output // false |
1 2 3 4 5 6 7 8 9 10 | String.prototype.test = function () { 'use strict'; console.log(typeof this === 'string'); }; 'a'.test(); // output // true |
注意,ecmascript 5中引入了
以下是在ES6和ES7中触发严格模式的条件:
- Global code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1.1).
- Module code is always strict mode code.
- All parts of a ClassDeclaration or a ClassExpression are strict mode code.
- Eval code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct eval (see 12.3.4.1) that is contained in strict mode code.
- Function code is strict mode code if the associated FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, or ArrowFunction is contained in strict mode code or if the code that produces the value of the function’s [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.
- Function code that is supplied as the arguments to the built-in Function and Generator constructors is strict mode code if the last argument is a String that when processed is a FunctionBody that begins with a Directive Prologue that contains a Use Strict Directive.
开发人员使用
防止意外声明全局变量。使用
1 2 3 4 5 6 7 8 9 10 11 | 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'}; } |
字符串
1 2 | "use strict"; var arguments = 3.14; // This will cause an error |
将限制关键字作为变量的使用。尝试使用它们会引发错误。
简而言之,这将使代码不易出错,反过来又会使您编写好的代码。
要了解更多信息,请参阅此处。
"use strict";是ECMA使JavaScript更加健壮的努力。它引入了JS,试图使其至少有一点"严格"(其他语言自90年代以来实现了严格的规则)。它实际上"迫使"JavaScript开发人员遵循某种编码最佳实践。不过,JavaScript非常脆弱。没有类型化变量、类型化方法等。我强烈建议JavaScript开发人员学习一种更健壮的语言,如Java或ActuScript 3,并在JavaScript代码中实现相同的最佳实践,它将工作得更好,调试更容易。
使用"严格"用于显示常见错误和重复错误,以不同方式处理,并更改Java脚本运行的方式,这些更改是:
防止意外的全局变量
无多重记录
消除与
消除这种胁迫
安全评估()
不可改变引发的错误
您还可以阅读本文了解详细信息
EcmaScript 5中引入了javascript"严格"模式。
1 2 3 4 | (function() { "use strict"; your code... })(); |
在JS文件的最上面写入
如果试图分配给未声明的变量,则显示错误
阻止覆盖密钥JS系统库
禁止某些不安全或容易出错的语言功能
浏览器兼容性问题:"use"指令旨在向后兼容。不支持它们的浏览器只会看到一个字符串文字,这个字符串文字不会被进一步引用。所以,他们会越过它继续前进。
通常,JavaScript不遵循严格的规则,因此错误的几率会增加。在使用
如果使用
"use strict";定义javascript代码应在"严格模式"。
- "use strict"指令在ECMAScript版本5中是新的。
- 它不是语句,而是由前面忽略的文本表达式JavaScript的版本。
- "使用严格"的目的是表示代码应该在"严格模式"下执行。
- 例如,使用严格模式时,不能使用未声明的变量。
除Internet Explorer 9及更低版本外,所有现代浏览器都支持"严格使用"。
劣势
如果开发人员使用的库处于严格模式,但开发人员习惯于在正常模式下工作,那么他们可能会对库调用一些无法按预期工作的操作。
更糟糕的是,由于开发人员处于正常模式,因此他们没有抛出额外错误的优势,因此错误可能会无声地失败。
此外,如上所列,严格模式阻止您做某些事情。
人们通常认为您不应该首先使用这些东西,但是一些开发人员不喜欢这种约束,并且希望使用语言的所有特性。
对于基本示例和参考,请浏览:
https://www.tutorialsteacher.com/javascript/javascript-strict