严格模式(use strict)
目的
- 消除JS中一些不合理、不严谨之处,减少一些怪异行为
- 消除代码中的一些不安全之处,保障代码运行安全
- 提高编译器效率,增加运行速度
- 为以后的JS新规范做铺垫
兼容性
FF、Chrome、IE10+、Safari、Opera
语法
"use strict";
老版本浏览器将以上源码当做字符串处理
使用范围
- 在整个脚本之前调用,整段脚本以严格模式执行
<script>
"use strict";
console.log('全局严格模式');
</script>
- 在函数内部之前调用,整个函数以严格模式执行
function fn() {
"use strict";
console.log('局部严格模式,只在函数内有效');
}
对行为和语法的控制
- 全局变量显示声明
- 正常模式下,变量没有声明,直接赋值,默认为全局变量;
- 严格模式禁止这种行为,全局变量必须用
var
显式声明
//正常模式下
a = 1;
console.log(a);//1
//严格模式下
"use strict";
a = 1;
console.log(a);//报错
- 禁止使用
with
width
语句在编译时无法确定属性归属于哪个对象 - 增加
eval
作用域- 正常模式下,
eval
中执行的作用于取决于它处于全局还是函数作用域内; - 严格模式下,
eval
本身有独立的作用域
- 正常模式下,
//正常模式下
var a = 1;
console.log(eval('var a = 1;a'));//2
console.log(a);//2
//严格模式下
var a = 1;
console.log(eval('var a = 2;a'));//2
console.log(a);//1
this
默认不指向全局对象window
- 正常模式下,
this
指向window
; - 严格模式下,
this
不再默认指向window
- 正常模式下,
//正常模式下
function fn() {
this.a = 1;
}
fn();
a;//1
//严格模式下
"use strict";
function fn() {
this.a = 1;
}
fn();
a;//报错
arguments
和caller
被禁用- 正常模式下,函数本身拥有默认属性
arguments
指向传递的参数,caller
指向函数引用; - 严格模式下,
arguments
和caller
被禁用,报错
- 正常模式下,函数本身拥有默认属性
- 禁止删除变量
- 正常模式下,
delete
可以删除定义的变量; - 严格模式下,只有
configurable
为true
的对象属性才能被删除,var
定义的变量不能被删除
- 正常模式下,
//正常模式下
var a = 1;
delete a;//a不会被删除,也不报错
a;//1
var obj = {
o1: 1,
o2: 2
};
delete obj.o1;//obj中o1属性被删除
obj.o1;//undefined;
//严格模式下
"use strict";
var a = 1;
delete a;//报错
a;//1
var obj = {
o1: 1,
o2: 2
};
delete obj.o1;
obj.o1;//undefined;
- 对只读属性赋值,会报错
- 正常模式下,对只读属性赋值时,不报错,只默认失败;
- 严格模式下,报错
- 对
getter
方法赋值报错 - 对禁止扩展的对象添加新属性报错
- 删除不可删除的属性报错
- 对象不能有重名属性
- 正常模式下,对象中重名属性会被后面的重名属性覆盖;
- 严格模式下,语法错误,不会报错
- 函数不能有重名参数
- 正常模式下,函数下有重名参数时,正常输出参数,重名参数被后面的重名参数覆盖,使用
arguments
输出时,可区分参数值; - 严格模式下,报错
- 正常模式下,函数下有重名参数时,正常输出参数,重名参数被后面的重名参数覆盖,使用
//正常模式下
function fn(a, a, b) {
console.log(a);
console.log(arguments[0]);
console.log(arguments[1]);
}
fn(1,2,3);//2 1 2
//严格模式下
"use strict";
function fn(a, a, b) {
console.log(a);
console.log(arguments[0]);
console.log(arguments[1]);
}
fn(1,2,3);//报错
- 禁用八进制
- 正常模式下,整数第一位如果是
0
,表示八进制,可正常转换输出对应的十进制数; - 严格模式下,报错
- 正常模式下,整数第一位如果是
//正常模式下
console.log(012);//10
//严格模式下
'use strict';
console.log(012);//报错
- 不允许对
arguments
赋值- 正常模式下,可对
arguments
重新赋值; - 严格模式下,语法错误,参数值不会变
- 正常模式下,可对
- 不再对
arguments
跟踪变化- 正常模式下,函数参数值发生变化时,
arguments
也随之变化; - 严格模式下,不变
- 正常模式下,函数参数值发生变化时,
//正常模式下
function fn(a, b, c) {
arguments[1] = 4;
console.log(a, b, c);//1, 4, 3
console.log(arguments[1]);//4
}
fn(1, 2, 3);
//严格模式下
'use strict';
function fn(a, b, c) {
arguments[1] = 4;
console.log(a, b, c);//1, 2, 3
console.log(arguments[1]);//4
}
fn(1, 2, 3);
arguments.callee
被禁用- 正常模式下,
arguments.callee
指向函数引用; - 严格模式下,被禁用,报错
- 正常模式下,
//正常模式下
function fn(a) {
console.log(arguments.callee);
}
fn(1);//输出原函数体
//严格模式下
'use strict';
function fn(a) {
console.log(arguments.callee);
}
fn(1);//报错
- 函数必须被声明在顶层
- 正常模式下,函数可以被声明在
if
或for
代码块内; - 严格模式下,不允许,报错
- 正常模式下,函数可以被声明在
//正常模式下
if(true) {
function fn(a) {
console.log(a);
}
}
fn(1);//1
//严格模式下
'use strict';
if(true) {
function fn(a) {
console.log(a);
}
}
fn(1);//报错,函数不存在
- 新增保留字
- 严格模式下,新增关键字
implements
、interface
、let
、package
、private
、protected
、public
、static
、yield
- 严格模式下,新增关键字