严格模式 - "use strict"
1. 严格模式作用域
1 整个脚本文件开启严格模式
所有语句之前放"use strict"
所有该脚本的子级作用域也会设置为严格模式
注意: 严格模式和非严格模式脚本混合会存在问题
//0.js
"use strict"
function strictTest0() {
//函数内部也会设置为严格模式
a = 1;//函数调用时报错
}
strictTest0();
//1.js
"use strict";
!function strictTest0() {
a = 1;
}()
//等同于
"use strict";
(function strictTest0() {
a = 1;
})()
//1-1.js
var a = 1;
"use strict";//严格模式写在第二行不起作用
(function strictTest0() {
a = 1;
})()
小技巧: 在函数声明(function)前加"!"可以让解释器理解为函数表达式而非函数声明,这样在末尾加()可以立即调用
2 为函数开启严格模式
c = 1;//并不会报错
function strictTest() {
"use strict"
a = 1;//函数调用时报错
}
strictTest();
3 多个<Script>标签之间的严格模式
严格模式在多个Script标签之间并不互相影响
<script>
"use strict"
a = 1;//报错
</script>
<script>
b = 1;//不报错
</script>
4 花括号{}内使用严格模式
不要在封闭大括弧 {} 内这样做,在这样的上下文中这么做是没有效果的
2. 严格模式作用
//2.js
"use strict";
with({ x: 1 }) {console.log(x);}//报错,不允许使用with
a = 1; //报错,不允许给未声明的变量赋值
var obj = { x: 1, x: 2 }; //IE10+报错。IE7~9、Chrome、FF不报错,结果为:2
console.log(0123); //报错,禁止八进制字面量
//保留的关键字,不能用这些名字作为变量名或者形参名
//eval, arguments, implements, interface, let, package, private, protected, public, static 和 yield
function test(a, a, b) { //声明时即会报错,不允许同名参数名
console.log(a + b);
}(1, 2, 3);
(function(a) {
'use strict';
arguments[0] = 100;//arguments和a并指向同一个值的引用,a作为副本存在; 但如果传的参数是对象,仍然指向用一个引用({x:1})
console.log(a); //1
console.log(arguments[0]); //100
delete a; //SyntaxError(语法错误)
eval('var evalVal = 2;'); //eval严格模式下为独立作用域
console.log(typeof evalVal); //undefined
function fun() { return this; } //严格模式的this指针指向undefined
console.log( fun() ); //undefined
})(1);
//非严格模式下执行以下函数
(function(a) {
arguments[0] = 100;//arguments和a指向同一个值的引用
console.log(a); //100
console.log(arguments[0]); //100
delete a;//非严格模式返回false,静默失败。(静默失败:不报错也没有任何效果)
eval('var evalVal = 2;'); //eval非独立作用域
console.log(typeof evalVal); //number
function fun() { return this; } //非严格模式的this指针指向Window
console.log( fun() ); //Window
})(1);
(function (a, a, b) {//最后一个重名参数会覆盖之前的重名参数
console.log(a + b); //5
})(1, 2, 3);