原文: http://pij.robinqu.me/JavaScript_Core/JavaScript_Basics/Strict_Mode.html
- 本文须要补充更多例子
- 本文存在讲明,但该网站的Markdown编辑器不支撑,所以没法一般展现,请到原文参考。
Strict Mode和Extended Mode
本文上一个版本盗用了他人的文章,经读者指出后我就删掉了。因为草拟的时候在客岁,我也不太清晰当初是怎样把他人的文章复制进来的。本文除了引见所谓的Strict Mode以外,还会引见其他关联内容。
JavaScript并非一个圆满的言语。事实上,第一个版本的Brendan Eich1消费十天的时候制造的,你不能对它希冀太多。以后,JavaScript在浏览器大战中,成为各方比赛的重要疆场。各大厂商各显神通,其副作用是种种奇奇怪怪的行动和各式不一的API。在以后,W3C和其他社区整体消费了大批的精神来经由过程规范化来“净化”一切Web开辟相干的手艺规范。
但为难的是,浏览器厂商并非那末完整的完成了W3C和ECMAScript的种种规范。末了,经验丰富的Javascript程序员,经由过程束缚自身对Javascript的运用方法,来到达让Javascript更高的可拥度。能够大部份人都读过《JavaScript言语精炼》2这本书,其报告的就是如安在JavaScript言语中,取其精华,然后去其糟粕。
而JavaScript的严厉形式,则是另一种紧箍咒,它的束缚力来自运转时自身,而不是用户的主观行动。也就是说,有许多含糊其词,或是毛病却被许可的操纵,被完全制止了。现在支撑严厉形式的支撑局限3从IE10起跳,其他常青浏览器也都是支撑的。
怎样开启
开启全局形式只需在一切语句之前安排"use strict"
字符串常量。
全局开启严厉形式:
"use strict"
var v = "Hello world";
但注重,如许会致使全部剧本内的代码都在严厉形式中实行。如果之前有些代码并没有斟酌严厉形式,这能够让你的全部应用程序倏忽失效。
我们更加引荐的是,在某个函数内开启严厉形式:
function mySuperMethod() {
"use strict";
var v = "Hello world";
}
function mySuckingMethod {
//not in strict mode
}
严厉形式的详细行动
人人有须要记着一堆言语特征了。然则,还好这些内容是把“歪”的掰“直”了。有少数代码例子来自于MDC4。
抛出ReferenceError
试图隐式建立全局变量
``` "use strict" hello = "world"//throw ```
抛出TypeError
试图修正已被定义为不可写的属性
``` "use strict"; var o = {}; Object.defineProperty(o, "hello", {value:"world", wrtiable:false}); o.hello = "bad boy";//throw ```
其他相似的另有:
- 给只读属性赋值
- 给不可扩大的对象新建属性
试图删除不可删除的属性
``` "use strict"; delete Object.prototype; //throw ```
arguments.callee
不能被返回、删除、修正;``` "use strict"; var fun = function() { return arugments.callee;//throw }; ```
抛出SyntaxError
反复定义属性名
``` "use strict"; var o = {hello: 1, hello: 2};//throw ```
禁用八进制字面量
``` "use strict"; var hello = 015;//throw ```
不许可反复参数名
``` function myMethod(a, b, b) {//throw "use strict"; } ```
不能运用
with
``` "use strict"; var obj = {}; with (obj) {};//throw ```
不许可对
eval
或arguments
赋值``` var fun = function(){ "use strict"; eval=16 }(); ```
不可将
eval
或arguments
作为参数名、变量名``` var fun = function(){ "use strict"; var obj = { set p(arguments) {} }; }(); ```
eval
被限定在暂时的当地作用域
eval不再有权限直接修正其地点作用于,而只能影响自身建立的作用域。
var hello = "world";
var evalHello = eval("'use strict'; var hello = "girl"; hello");
// hello === "world"
// evalHello === "girl"
arguments
不再追踪现实参数值变化
function f(hello)
{
"use strict";
hello = "girl";
return [hello, arguments[0]];
}
var pair = f("world");
// pair[0] === "girl"
// pair[1] === "world";
函数的动态绑定后的this
不做任何修正
- 纵然指定
null
或undefined
,引擎也不会从新指定全局对象作为this
- 指定基本数据类型时,也不会用包装类举行转换
"use strict";
function fun() { return this; }
// fun() === undefined
// fun.call(2) === 2
// fun.apply(null) === null
// fun.call(undefined) === undefined
// fun.bind(true)() === true
挪用客栈不可被追踪
以往,我们能够经由过程函数的caller
和arguments
来投影全部挪用客栈。然则,在严厉形式中我们做不到。
function restricted()
{
"use strict";
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
ECMAScript6的相干特征
更多保留字
implements, interface, let, package, private, protected, public, static, yield
仅许可在开首运用function语句
许多开辟者喜好以下代码作风,这在严厉形式中会报错。
function foo()
{
"use strict";
return g;
function g() { }//throw SyntaxError
}
这个转变的原因是,JavaScript的Hoisting
特征会让许多人疑惑:
function g() { }
function foo()
{
if (true)
function g() { }
return g;
}
Extended Mode
ES6 Draft中引入了一个新的观点5,叫Extend Mode
,然后又被撤销了6。但不幸的是,V8中已支撑了这个新形式。所以,作为事实规范,现在依靠V8的一切Javascript运转环境都有以下三个形式:
- Classic Mode,或许Non-strict mode
- Strict Mode
- Extended Mode
这个形式是备受争议的。这个形式的发生,也体会出制造一个规范的难题的地方——你总要斟酌新规范对老规范的兼容,尤其是Web手艺。
有轻微相识ES6的同砚都应该清晰,module
、class
这些东西已完整推翻了传统JavaScript的许多尝试。但也有不少东西,开辟者是能够接收,并立马去尝试的。于是乎,关于怎样让代码部份进入extended mode
也就成了最初议论的重点7。
现实表现上,node的0.11.x的版本,有些特征,仅仅运用--harmony
并不能完整运用,还需加上--use_strict
。在这里,已能够看出V8团队有多纠结了8。他们也没有想清晰,该怎样进入extended mode
,干脆,也叫strict
吧。
现在仅在extended mode
下可用的ES6特征:
- let
- blockl-level function declaration
关于ES6的特征,请参考本书的相干章节。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Strict_mode ↩
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts ↩
http://wiki.ecmascript.org/lib/exe/fetch.php?id=harmony%3Aspecification_drafts&cache=cache&media=harmony:working_draft_ecma-262_edition_6_11-7-11.pdf ↩
https://lists.webkit.org/pipermail/webkit-dev/2011-December/018903.html ↩