严格模式(Strict mode)是由ECMA-262规范定义的新兴JavaScript标准,第五版发布于2009年12月。旨在改善错误检查功能并且标识可能不会延续到未来JavaScript版本的脚本。ES5严格模式是限制性更强的JavaScript变体,它与常规JavaScript的语义不同,其分析更为严格。

目前,除了IE6-9,其它浏览器均已支持ES5严格模式。

一、严格模式的使用

严格模式的使用很简单,只有在代码首部加入字符串  "use strict"。有两种应用场景,一种是全局模式,一种是局部模式。

1)全局模式

'use strict'
var globalVal = 100
console.log(globalVal)

执行后输出了100,与非严格模式没什么区别。

2)局部模式

将"use strict"放到函数内的第一行,如下

function func() {
'use strict'
var localVal = 200
console.log(localVal)
}
func()

执行后输出了200,与非严格模式也没用什么区别。

3)模块模式

如果你想定义一个模块或者一个小库,自然采用一个匿名函数自执行是不错的选择

~function() {
"use strict"; // Define your library strictly...
}();

“use strict” 的位置是很讲究的,必须在首部。首部指其前面没有任何有效js代码。以下都是无效的,将不会触发严格模式。

a)“use strict” 前有代码

var width = 10
'use strict'
globalVar = 100

b)“use strict” 前有个空语句都不行

;
'use strict'
globalVar = 100

function func() {
;
'use strict'
localVar = 200
}

function func() {
;'use strict'
localVar = 200
}

  

当然,“use strict”前加注释是可以的

// strict mode
'use strict'
globalVar = 100

function func() {
// strict mode
'use strict'
localVar = 200
}
func()

二、严格模式下的执行限制

上面举的两个例子,在严格模式中输出与普通模式没用什么区别。下面就不一样了。

1)不使用var声明变量严格模式中将不通过

我们知道JS是弱类型,宽松的语言。不使用var声明的变量默认转为全局变量。但在严格模式中将不允许,会报语法错误。

'use strict'
globalVal = 100

执行,Firebug提示如下

又如全局的for循环

'use strict'
for (i=0; i<5; i++) {
console.log(i)
}

这种写法在非严格模式中很危险,i 会不小心溢出成为全局变量。但在严格模式中会报错

局部模式

function func() {
'use strict'
localVal = 200
console.log(localVal)
}
func()

执行,Firebug报错

因此,严格模式中声明变量务必记得加一个var。

2)任何使用'eval'的操作都会被禁止

'use strict'
var obj = {}
var eval = 3
obj.eval = 1
obj.a = eval
for (var eval in obj) {}
function eval() {}
function func(eval) {}
var func = new Function('eval')

Firebug报错

3)eval作用域

JS中作用域有两种,全局作用域和函数作用域。严格模式带来了第三种作用域:eval作用域,如下

'use strict'
var a = 10
eval('var a = 20; console.log(a)')
console.log(a)

Firebug控制台依次输出了20,10。eval是在全局模式下(非函数内)的,如果不加严格模式,此时修改的是全局的a。即输出20,20。见 eval与window.eval的差别

4)with被禁用

'use strict'
with({a:1}) { }

Firebug报错

5)caller/callee 被禁用

function func() {
'use strict'
arguments.callee
arguments.caller
}
func()

Firebug报错

6)对禁止扩展的对象添加新属性会报错

'use strict'
var obj = {}
Object.preventExtensions(obj)
obj.a = 1 // 报错

Firebug报错

7)删除系统内置的属性会报错

'use strict'
delete Object.prototype // 报错
delete Function.prototype // 报错

Firebug 报错

8)delete使用var声明的变量或挂在window上的变量报错

'use strict'
var obj = {a:1}
window.a = 1
delete obj // 报错
delete a // 报错

Firebug报错

9)delete不可删除属性(isSealed或isFrozen)的对象时报错

'use strict'
var obj = {a: 1}
Object.seal(obj)
delete obj.a

Firebug报错

10)对一个对象的只读属性进行赋值将报错

'use strict'
var obj = {}
Object.defineProperty(obj, 'a', {value: 1, writable: false})
obj.a = 2 // 报错

Firebug报错

11)对象有重名的属性将报错

'use strict'
var obj = {
a: 1,
a: 2
}

Firebug报错

而在非严格模式中,后面的属性将覆盖前面的属性,即obj.a等于2。

12)函数有重名的参数将报错

'use strict'
function func(a, a) {
alert(a)
}
func()

Firebug报错

而在非严格模式中,后面的同名参数将覆盖前面的。

13)八进制表示法被禁用

'use strict'
var num = 022

Firebug报错

14)arguments严格定义为参数,不再与形参绑定

先看非严格模式代码

function func(a) {
arguments[0] = 2
alert(a) // 2
}
func(1)

func调用时传参为1,函数内部通过arguments修改为2,此时alert的为修改后的2。 而在严格模式中则不能被修改,如下

'use strict'
function func(a) {
arguments[0] = 2
alert(a) // 1
}
func(1)

显示的严格的为传入的1。

其实有点还有点复杂,如果alert的是arguments[0],实际在严格模式中仍然被修改为2了。如下

'use strict'
function func(a) {
arguments[0] = 2
alert(arguments[0]) // 2
}
func(1)

可以参考下 仅Chrome中函数实参与形参发生关联

15)函数必须声明在顶层

我们知道函数声明和函数表达式是两个不同的概念。一般函数声明都在最顶层,ES5前的JS宽松,你可以写在if或for内(强烈鄙视这种写法)。当然Firefox的解析方式与其他浏览器不同,见SJ9002。而在严格模式中这些写法将直接报错

'use strict'
if (true) {
function func1() { } // 语法错误
}
for (var i = 0; i < 5; i++) {
function func2() { } // 语法错误
}

Firebug报错

16)ES5里新增的关键字不能当做变量标示符使用,如implements, interface, let, package, private, protected, public, static, yield

'use strict'
var let = 10
var yield = 20

Firebug报错

17)call/apply的第一个参数直接传入不包装为对象

'use strict'
function func() {
console.log(typeof this)
}
func.call('abcd') // string
func.apply(1) // number

Firebug输出如下

依次为"string","number"。而在非严格模式中call/apply将对值类型的"abcd",1包装为对象后传入,即两次输出都为"object"。

18)call/apply的第一个参数为null/undefined时,this为null/undefined

这里以call来示例

'use strict'
function func() {
console.log(this)
}
func.call(undefined) // undefined
func.call(null) // null

Firebug输出如下

依次是undefined,null。而非严格模式中则是宿主对象,浏览器里是window,node.js环境则是global。

19)bind的第一个参数为null/undefined时,this为null/undefined

bind是ES5给Function.prototype新增的一个方法,它和call/apply一样在function上直接调用。它返回一个指定了上下文和参数的函数。当它的第一个参数为null/undefined时,情形和call/apply一样,this也为null/undefined。

'use strict'
function func() {
console.log(this)
}
var f1 = func.bind(null)
var f2 = func.bind(undefined)
f1() // null
f2() // undefined

而在非严格模式中输出的都是window(或global)。

相关:

Mozilla strict mode

http://msdn.microsoft.com/library/br230269.aspx

http://java-script.limewebs.com/strictMode/test_hosted.html

http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/

http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/

JavaScript中delete操作符不能删除的对象

ES5严格模式(Strict mode)的更多相关文章

  1. mysql 严格模式 Strict Mode说明(text 字段不能加默认或者 不能加null值得修改方法)

    mysql 严格模式 Strict Mode说明 1.开启与关闭Strict Mode方法找到mysql安装目录下的my.cnf(windows系统则是my.ini)文件 在sql_mode中加入ST ...

  2. mysql 严格模式 Strict Mode

    mysql 严格模式 Strict Mode 找到MySQL安装目录下的my.cnf(windows系统则是my.ini)文件 在sql_mode中加入STRICT_TRANS_TABLES则表示开启 ...

  3. Javascript 严格模式 strict mode(转)

    一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode).顾名思义,这种模式使得Javascript在更严格的条件下运行. ...

  4. es5严格模式简谈

    一.用法: 在全局或局部开头加上“use strict”即可 就是一行字符串,不会对不兼容严格模式的浏览器产生影响.二.不再兼容es3的一些不规则语法.使用全新的es5规范.三.两种用法: 全局严格模 ...

  5. JavaScript严谨模式(Strict Mode)

    下面的内容翻译自It’s time to start using JavaScript strict mode,作者Nicholas C.Zakas参与了YUI框架的开发,并撰写了多本前端技术书籍,在 ...

  6. MySQL模式 : Strict Mode

    I. Strict Mode阐述 根据 mysql5.0以上版本 strict mode (STRICT_TRANS_TABLES) 的限制: 1).不支持对not null字段插入null值 2). ...

  7. Javascript 严格模式(strict mode)详解

    Javascript 严格模式详解   一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode).顾名思义,这种模式使得Ja ...

  8. 从零开始学 Web 之 ES6(一)ES5严格模式

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  9. mysql 严格模式 Strict Mode说明(转)

    转自https://www.cnblogs.com/jhcelue/p/7290243.html 1.开启与关闭Strict Mode方法 找到mysql安装文件夹下的my.cnf(windows系统 ...

随机推荐

  1. ajax请求跨域问题

    ajax跨域,这个是面试的时候常被问到,也是在做项目的时候会遇到的问题,在之前的项目中就有遇到过,这里根据经验写了三种分享下 1.使用中间层过渡的方式 简单来说就是"后台代理",把 ...

  2. 【jQuery基础学习】12 jQuery学习感想

    学习完<锋利的jQuery>,用时13天. 这期间,私底下又用了一点时间去W3C上把HTML和CSS重新过了一遍. 总的来说,收获还是蛮多的. 其实在本书里面真正重要的也就前几章,后面的都 ...

  3. C#的注释和快速开启工具的命令

    1.注释的方法 1)sqlserver中,单行注释:——   多行注释:/****/ 2)C#中,单行注释://    多行注释:/****/ 3)C#中多行注释的快捷方式:启用ctrl+E+C ,撤 ...

  4. LeetCode2:Median of Two Sorted Arrays

    题目: There are two sorted arrays A and B of size m and n respectively. Find the median of the two sor ...

  5. 织梦CMS的MVC体系

    13年无意中翻看DedeCMS的代码,发现DedeCMS中是有了一个基本MVC框架的,在现有的版本中,主要是应用到了ask.book等模块上. 织梦这个东西,里面很多设计思想是非常优秀的,但整体代码的 ...

  6. yii2.0 图片上传(摘录)

    文章来源:http://blog.sina.com.cn/s/blog_88a65c1b0101izmn.html 下面小伙就带领大学学习一下 Yii2.0 的图片上传类的使用,还是老样子,如果代码样 ...

  7. Hibernate中的脏检查和缓存清理机制

    脏检查 Session到底是如何进行脏检查的呢?当一个Customer对象被加入到Session缓存中时,Session会为Customer对象的值类型的属性复制一份快照.当Session清理缓存时, ...

  8. 成熟的RosettaNet解决方案软件介绍

    RosettaNet是一套B2B标准,以标准来优化供应链管理流程,它可以缩短整个供应链各个供货周期.RosettaNet 标准为电子商务标准化提供一个健壮的.非专有的解决方案,它是免费的,通过 Ros ...

  9. 【GPU编解码】GPU硬解码---DXVA

    前面介绍利用NVIDIA公司提供的CUVID库进行视频硬解码,下面将介绍利用DXVA进行硬解码. 一.DXVA介绍 DXVA是微软公司专门定制的视频加速规范,是一种接口规范.DXVA规范制定硬件加速解 ...

  10. CentOS安装Erlang

    1.首先要安装编译源码用的编译器gcc&g++,安装方式很简单,先用yum search gcc搜索出包,然后选择适合自己的版本复制全名,用yum intall gcc_XXX来进行安装即可. ...