摘要:之后,在浏览器大战中,成为各方角逐的主要战场。各大厂商各显神通,其副作用是各种奇奇怪怪的行为和各式不一的。也就是说,有很多模棱两可,或是错误却被允许的操作,被彻底禁止了。目前支持严格模式的支持范围从起跳,其他常青浏览器也都是支持的。
原文: http://pij.robinqu.me/JavaScript_Core/JavaScript_Basics/Strict_Mode.html
源代码: https://github.com/RobinQu/Programing-In-Javascript/blob/master/chapters/JavaScript_Core/JavaScript_Basics/Strict_Mode.md
本文需要补充更多例子
本文存在批注,但该网站的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的特性,请参考本书的相关章节。
http://en.wikipedia.org/wiki/Brendan_Eich ↩
http://book.douban.com/subject/3590768/ ↩
http://caniuse.com/#feat=use-strict ↩
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 ↩
https://code.google.com/p/v8/source/detail?r=10062 ↩
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/78152.html
原文: http://pij.robinqu.me/Javascript_Core/Javascript_Basics/Strict_Mode.html 源代码: https://github.com/RobinQu/Programing-In-Javascript/blob/master/chapters/Javascript_Core/Javascript_Basics/Strict...
摘要:前三个是为了解决变量声明定义的问题,而最后一个则影响最大。下文只介绍前三个特性。这是因为的的不支持块级作用域,变量仅仅被限制到函数作用域内。 原文: http://pij.robinqu.me/JavaScript_Core/ECMAScript/es6/es6_syntax_features.html 源代码: https://github.com/RobinQu/P...
摘要:前三个是为了解决变量声明定义的问题,而最后一个则影响最大。下文只介绍前三个特性。这是因为的的不支持块级作用域,变量仅仅被限制到函数作用域内。 原文: http://pij.robinqu.me/JavaScript_Core/ECMAScript/es6/es6_syntax_features.html 源代码: https://github.com/RobinQu/P...
摘要:前三个是为了解决变量声明定义的问题,而最后一个则影响最大。下文只介绍前三个特性。这是因为的的不支持块级作用域,变量仅仅被限制到函数作用域内。 原文: http://pij.robinqu.me/JavaScript_Core/ECMAScript/es6/es6_syntax_features.html 源代码: https://github.com/RobinQu/P...
摘要:字符串不能用作标识符变量或函数名参数名等在严格模式下,函数声明无法嵌套在语句或块中。严格模式下用法无效如果在函数内声明变量,则不能在此函数外部使用该变量。在严格模式下,更改的值不会影响的值,因为对象只是一个本地副本。 本文同步自 我的博客,地址:http://reeoo.me/archives/strictmode.html 什么是严格模式 我们平时写的JavaScript代码一般都运...
阅读 3738·2019-08-30 12:58
阅读 1086·2019-08-29 16:37
阅读 3049·2019-08-29 16:29
阅读 3264·2019-08-26 12:18
阅读 2539·2019-08-26 11:59
阅读 3632·2019-08-23 18:27
阅读 3079·2019-08-23 16:43
阅读 3492·2019-08-23 15:23