严格模式:js的一种运行模式,设立严格模式主要有以下几个:
1、消除js语法的一些不合理、不严谨之处,减少一些怪异行为;
2、消除代码运行的一些不安全之处,保证代码运行的安全;
3、提高编译器效率,增加运行速度;
4、为未来新版本的js做好铺垫。
语法和行为的改变:
1、全局变量显示声明:在非严格模式下,一个变量如果没有声明就使用会被隐式为全局变量,但是严格模式下禁止这种用法、严格模式下,变量都必须先用var命令声明,然后在使用。测试如下:
2、静态绑定:
js语言有允许“动态绑定”的特点(即某些属性和方法到底属于哪一个对象不是在编译时确定的。而是在运行时确定的)。
严格模式对动态绑定做了一些限制。在某些情况下,只允许静态绑定,也就是说属性和方法到底属于哪一个对象,在编译阶段就确定了,这样有利于编译效率的提高,也使得代码更容易阅读,更少出现意外。
a、禁止使用with语句:因为with语句无法在编译时就确定属性到底属于哪个对象。
b、创建eval作用域:非严格模式下,js有两种变量作用域(全局作用域和函数作用域)严格模式下创建第三种作用域:eval作用域
非严格模式:eval语句的作用域取决于它处于全局作用域还是处于函数作用域。
严格模式:eval语句的作用域本身就是一个作用域,不再能够生成全局全局变量,它所生成的变量只能用于eval内部。
测试如下:
3、增强安全性
a、禁止this关键字指向全局对象
function f(){
return !this;
}
// 返回false,因为"this"指向全局对象,"!this"就是false
function f(){
"use strict";
return !this;
}
// 返回true,因为严格模式下,this的值为undefined,所以"!this"为true。
因此,使用构造函数时,如果忘了加new,this不再指向全局对象,而是报错。
测试如下:
b、禁止在函数内部遍历调用栈
测试如下:
4、禁止删除变量
严格模式下无法删除变量。只有configurabale设置为true的对象属性才能被删除。
测试如下:
5、显示报错:
正常模式下,对一个对象的只读属性进行赋值,不会报错只会失败,但严格模式下将会报错:
6、重名错误:
a、对象不能有重名属性、函数不能有重名参数:
1:正常模式下,如果对象有多个重名属性,最后赋值的那个属性会覆盖前面的值。严格模式下,这属于语法错误。
2:正常模式下,如果函数有多个重名的参数,可以用arguments[i]读取。严格模式下,这属于语法错误。
测试如下:
7、禁止使用八进制:
正常模式下,整数的第一位如果是0,表示这是八进制数,比如0100等于十进制的64。严格模式禁止这种表示法,整数第一位为0,将报错。
8、arguments对象的限制
arguments是函数的参数对象,严格模式对它的使用做了限制。限制如下
a、arguments不再追踪参数变化
测试如下:
b、不允许对arguments赋值
"use strict";
arguments++; // 语法错误
var obj = { set p(arguments) { } }; // 语法错误
try { } catch (arguments) { } // 语法错误
function arguments() { } // 语法错误
var f = new Function("arguments", "'use strict'; return 17;"); // 语法错误
c、禁止使用arguments.callee(无法在匿名函数内部调用自身):
测试如下:
9、保留字:
为了向将来Javascript的新版本过渡,严格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。
使用这些词作为变量名将会报错
此外,ECMAscript第五版本身还规定了另一些保留字(class, enum, export, extends, import, super),以及各大浏览器自行增加的const保留字,也是不能作为变量名的。