严格模式
JavaScript 的严格模式是使用受限制的 JavaScript 的一种方式,从而隐式地 退出 “草率模式”。严格模式不仅仅是 一个 子集:这种模式有意地与普通情形下的 代码 有所区别。(MDN)
严格模式为 JavaScript 提供了 一个 更严格的运行环境。
开启严格模式后,部分特性会发生改变,如 this 指向 window 的 函数 不再指向 window ,而是变成了 undefined 。
function Test @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ 'use strict' @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( 'this:' @H_ 404 _35@, this @H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} Test @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@; // 输出 :this: undefined
1. 开启严格模式
1.1 对单个 script 标签 或者 js 文件 开启严格模式
单个 js 文件 或者 script 标签 的严格模式,可以通过在所有 代码 执行前 加上 'use strict' 字符串开启。
'use strict' @H_ 404 _35@; function Test @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( 'this:' @H_ 404 _35@, this @H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} Test @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@; // 输出 :this: undefined
1.2 对 一个 函数 开启严格模式
在 函数 顶端协商 'use strict' 字符串,就可以打开整个 函数 的严格模式。
function testWith @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ 'use strict' @H_ 404 _35@; var person = @H_ 404 _35@{ name@H_ 404 _35@: '鸽子天王' @H_ 404 _35@, age@H_ 404 _35@: @H_ 404 _35@, @H_ 404 _35@} @H_ 404 _35@; var age = @H_ 404 _35@; with @H_ 404 _35@( person@H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( name@H_ 404 _35@) @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( age@H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} @H_ 404 _35@} testWith @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@;
在严格模式下是不提供 with 语句的 调用 的,所以这里会爆 Strict mode code may not include a with statement 错误 。
2. 严格模式的规范
2.1 禁止 使用 with
在严格模式下是 禁止 使用 with 语句的。
'use strict' @H_ 404 _35@; var person = @H_ 404 _35@{ name@H_ 404 _35@: '鸽子巨星' @H_ 404 _35@, @H_ 404 _35@} @H_ 404 _35@; with @H_ 404 _35@( person@H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( name@H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@}
2.2 变量必须被声明
在严格模式下,变量必须被声明才能使用,否则会报错。
// 非严格模式下 number = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( number@H_ 404 _35@) @H_ 404 _35@; // 输出 :1
// 严格模式下 'use strict' @H_ 404 _35@; number = @H_ 404 _35@; // 报错:ReferenceError: number is not defined
2.3 eval 会创建自己的作用域
非严格模式下的 eval 作用域是其本身所在的作用域,而严格模式下,eval 执行过程中会创建 一个 新的作用域,并在结束后销毁。
// 非严格模式下 var number = @H_ 404 _35@; eval @H_ 404 _35@( 'var number = 3; console.log(number)' @H_ 404 _35@) @H_ 404 _35@; // 输出 :3 console@H_ 404 _35@. log @H_ 404 _35@( number@H_ 404 _35@) @H_ 404 _35@; // 输出 :3
// 严格模式下 'use strict' @H_ 404 _35@; var number = @H_ 404 _35@; eval @H_ 404 _35@( 'var number = 3; console.log(number)' @H_ 404 _35@) @H_ 404 _35@; // 输出 :3 console@H_ 404 _35@. log @H_ 404 _35@( number@H_ 404 _35@) @H_ 404 _35@; // 输出 :1
2.4 函数 的 arguments 不能被 修改
在非严格模式下, 函数 的 arguments 可以被重新赋值,在严格模式下,做赋值操作会报错。
function fn @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( arguments@H_ 404 _35@) @H_ 404 _35@; arguments = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( arguments@H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} fn @H_ 404 _35@( @H_ 404 _35@, @H_ 404 _35@, @H_ 404 _35@) @H_ 404 _35@;
'use strict' @H_ 404 _35@; function fn @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( arguments@H_ 404 _35@) @H_ 404 _35@; arguments = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( arguments@H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} fn @H_ 404 _35@( @H_ 404 _35@, @H_ 404 _35@, @H_ 404 _35@) @H_ 404 _35@;
2.5 函数 的 this 规则有些变化
在 this 章节中讨论了不同情况的指向,其中有一种情况 函数 的 this 是指向 window 的。
在严格模式中,这种情况下的 this 会变成 undefined 。
function testThis @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( this @H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} testThis @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@;
// 严格模式下 'use strict' @H_ 404 _35@; function testThis @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( this @H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} testThis @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@;
2.6 caller 与 arguments.callee 被禁用
arguments.caller 可以 获取 到 调用 当前 函数 的 函数 的引用(该 属性 已经被标准废弃,不再使用了)。
arguments.callee 则可以 获取 到当前 函数 的引用。
这两个 属性 在严格模式下都被禁用。
function fn1 @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( arguments@H_ 404 _35@. callee === fn1@H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} fn1 @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@;
'use strict' @H_ 404 _35@; function fn1 @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@{ console@H_ 404 _35@. log @H_ 404 _35@( arguments@H_ 404 _35@. callee === fn1@H_ 404 _35@) @H_ 404 _35@; @H_ 404 _35@} fn1 @H_ 404 _35@( @H_ 404 _35@) @H_ 404 _35@;
2.7 删除 con fig urable 为 false 的 属性 时报错
在非严格模式下,这种情况会直接忽略。
var obj = @H_ 404 _35@{ @H_ 404 _35@} @H_ 404 _35@; Object@H_ 404 _35@. defineProperty @H_ 404 _35@( obj@H_ 404 _35@, 'prop' @H_ 404 _35@, @H_ 404 _35@{ con fig urable@H_ 404 _35@: false @H_ 404 _35@, value@H_ 404 _35@: @H_ 404 _35@, @H_ 404 _35@} @H_ 404 _35@) @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@) @H_ 404 _35@; delete obj@H_ 404 _35@. prop@H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@) @H_ 404 _35@;
'use strict' @H_ 404 _35@; var obj = @H_ 404 _35@{ @H_ 404 _35@} @H_ 404 _35@; Object@H_ 404 _35@. defineProperty @H_ 404 _35@( obj@H_ 404 _35@, 'prop' @H_ 404 _35@, @H_ 404 _35@{ con fig urable@H_ 404 _35@: false @H_ 404 _35@, value@H_ 404 _35@: @H_ 404 _35@, @H_ 404 _35@} @H_ 404 _35@) @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@) @H_ 404 _35@; delete obj@H_ 404 _35@. prop@H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@) @H_ 404 _35@;
2.8 修改 writable 为 false 的 属性 时会报错
在非严格模式下,这种情况会直接忽略。
var obj = @H_ 404 _35@{ @H_ 404 _35@} @H_ 404 _35@; Object@H_ 404 _35@. defineProperty @H_ 404 _35@( obj@H_ 404 _35@, 'prop' @H_ 404 _35@, @H_ 404 _35@{ writable@H_ 404 _35@: false @H_ 404 _35@, value@H_ 404 _35@: @H_ 404 _35@, @H_ 404 _35@} @H_ 404 _35@) @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@. prop@H_ 404 _35@) @H_ 404 _35@; obj@H_ 404 _35@. prop = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@. prop@H_ 404 _35@) @H_ 404 _35@;
'use strict' @H_ 404 _35@; var obj = @H_ 404 _35@{ @H_ 404 _35@} @H_ 404 _35@; Object@H_ 404 _35@. defineProperty @H_ 404 _35@( obj@H_ 404 _35@, 'prop' @H_ 404 _35@, @H_ 404 _35@{ writable@H_ 404 _35@: false @H_ 404 _35@, value@H_ 404 _35@: @H_ 404 _35@, @H_ 404 _35@} @H_ 404 _35@) @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@. prop@H_ 404 _35@) @H_ 404 _35@; obj@H_ 404 _35@. prop = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( obj@H_ 404 _35@. prop@H_ 404 _35@) @H_ 404 _35@;
2.9 禁止 书写八进制的字面量
八进制的表示是在数字前面加 一个 0 ,但其实 ECMAScript 标准中并没有这种表示法。
在 ES6 中提供了八进制数的表示方式,即在数字前 加上 0o 前缀。
在严格模式下是 禁止 使用 0 前缀表示的八进制字面量的。
// 非严格模式中 var num = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( num@H_ 404 _35@) @H_ 404 _35@; // 输出 :8
// 严格模式下 'use strict' @H_ 404 _35@; var num = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( num@H_ 404 _35@) @H_ 404 _35@; // 输出 :8
2.10 新增了一些不能作为变量的关键字
许多关键字在非严格模式下是可以当作变量名的。
var yield = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( yield @H_ 404 _35@) @H_ 404 _35@;
'use strict' @H_ 404 _35@; var yield = @H_ 404 _35@; console@H_ 404 _35@. log @H_ 404 _35@( yield @H_ 404 _35@) @H_ 404 _35@;
根据 MDN 提供的 内容 ,保留字有:
implements interface let package private protected public static yield
3. 小结
对严格模式大多数需要注意的是他带来的一些语法上的改变,特别是有些写法,在之前是不会报错的,开启严格模式后就会报错,如果没有进行 错误 处理,就会导致程序的中断。
以上对严格模式下的改变不一定是全部,可以参考 MDN 的文档。
作用域 ? ?JavaScript this声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did92451