JavaScript 严格模式(strict mode)即在严格的条件下运行。
"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。
使用严格模式的目的:
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
不支持strict模式的浏览器把"use strict"当做一个字符串语句执行,支持strict模式的浏览器将开启strict模式
"use strict" 指令在 JavaScript 1.8.5 (ECMAScript5) 中新增。
使用严格模式的目的:
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
消除代码运行的一些不安全之处,保证代码运行的安全;
提高编译器效率,增加运行速度;
不支持strict模式的浏览器把"use strict"当做一个字符串语句执行,支持strict模式的浏览器将开启strict模式
支持严格模式的浏览器包括IE10+、Firefox4+、safari12+、opera12+、chrome
<script>
console.log('---- 严格模式通过在脚本或函数的头部添加 "use strict" 表达式来声明。----');
/*在脚本头部声明 "use strict" 整个脚本都执行严格模式;即全局*/
/*在函数头部声明 "use strict" 只在函数内使用严格模式;即局部*/
x = 3.14; // 不报错
myFunction();
function myFunction() {
"use strict";
y = 3.14; // 报错 y is not defined
}
console.log('-----------------------一个小坑-------------------------------');
/* 如果将"use strict"放在脚本头部声明,当与另一个非严格模式的js合并时,会使其受严格模式约束,可能会报错,
所以建议代码都包在一个立即执行函数里面。(即一般局部使用)*/
(function(){
"use strict";
var name = "张三";
})();
console.log('-------------------1.不允许使用未定义的变量(变量约束)------------------------');
x1 = "aaa"; //error : x1 is not defined
y1 = {
a : 10,
b : 12
};
//error : y1 is not defined
console.log('------2.不允许删除变量,对象,函数(只有configurable设置为true的对象属性,才能被删除。)------');
var x2 = 3.14;
delete x2;
function a2(){};
delete a2;
//error: Delete of an unqualified identifier in strict mode.
var o = Object.create(null, {'x': {
value: 1,
configurable: true
}});
delete o.x; // 删除成功
console.log('-----------------------3.不允许对只读属性赋值-------------------------------');
var obj = {};
Object.defineProperty(obj, "x", {value:0, writable:false});
obj.x = 3.14;
//error: Cannot assign to read only property 'x' of object '#<Object>'
console.log('---------------------4.重名错误,不允许函数参数名重名--------------------');
function a3(x,x){
console.log(x);
};
a3(2,3);
//error: Duplicate parameter name not allowed in this context
/*对象不能有重名的属性*/
var o = {
p: 1,
p: 2
};
console.log(o.p);
// 有的说是错的,但是在chrome和火狐中试了试,没有报错,会取第二个值
console.log('-----------------------5.不允许使用八进制,转义字符------------------------');
var x4 = 010;
//error: Octal literals are not allowed in strict mode.
var x = '\010';
//error: Invalid or unexpected token
console.log('--------------6.不允许对一个使用getter方法读取的属性进行赋值---------------');
var obj = {get x() {return 0} };
obj.x = 3.14;
//error: Cannot set property x of #<Object> which has only a getter
console.log('-----------7.增强的安全措施,禁止this关键字指向全局对象。---------');
function f(){
return !this;
}
// 非严格模式返回false,因为"this"指向全局对象,"!this"就是false
function f(){
"use strict";
return !this;
}
// 严格模式返回true,因为严格模式下,this的值为undefined,所以"!this"为true。
var name="张三";
function done(){
console.log(this.name);
}
done();
// Cannot read property 'name' of undefined
// 严格模式this指函数对象,但是内部并没有定义name属性
console.log('-----------------------8.静态绑定-------------------------------');
/*不允许使用with语句*/
with(location){
alert(11111);
}
//Strict mode code may not include a with statement
/*创设eval作用域*/
// 正常模式下,Javascript语言有两种变量作用域(scope):全局作用域和函数作用域。严格模式创设了第三种作用域:eval作用域。
// 正常模式下,eval语句的作用域,取决于它处于全局作用域,还是处于函数作用域。
// 严格模式下,eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。
"use strict";
var x = 2;
console.info(eval("var x = 5; x")); // 5
console.info(x); // 2
console.log('-----------------9. 不能重新声明、删除或重写eval和arguments这两个标示符----------------------');
var eval = 1;
var arguments = 2;
// Unexpected eval or arguments in strict mode
/*arguments不再追踪参数的变化*/
function f(a) {
a = 2;
return [a,arguments[0]];
}
f(1); // 正常模式为[2,2]
function f(a) {
'use strict';
a = 2;
return [a,arguments[0]];
}
f(1); // 严格模式为[2,1]
/*禁止使用arguments.callee(正常模式下callee 属性的初始值就是正被执行的 Function 对象)*/
var f = function() { return arguments.callee; };
f(); // 报错
/*禁止在函数内部遍历调用栈*/
function f1(){
f1.caller; // 报错
f1.arguments; // 报错
}
f1();
// 严格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。