严格模式 vs 混杂模式

摘要:正常情况下我们写js都是在混杂模式下的,ES5定义了另外一种模式->严格模式
为什么叫严格模式?
严格模式就是让js语法更加合理,更加严谨,现在包括IE10在内的浏览器都支持严格模式。

下面我们来看看严格模式和混杂模式到底有什么不同~~~

如何使用严格模式?

1
'use strict';

简单的一句代码,放在script标签开头或者函数开头就可以了,下面的代码就会按严格模式进行解析,这个也是严格模式的一个特点就是可以针对局部代码进行使用严格模式。

严格模式与混杂模式的不同?

1.全局变量的显示声明

1
2
3
4
5
var a;
function fun(){
b = 1;
}
fun();

混杂模式:我们这样声明,a跟b都是全局变量
严格模式:报错->b是未定义的变量

2.对象不能有重名的属性

1
2
3
4
var a = {
p:1,
p:2
}

混杂模式:重名属性会使用最后一个的值
严格模式:报错->重名属性在严格模式下不允许
ps:谷歌,火狐在严格模式下的行为跟混杂模式是一样的,IE10在严格模式下显示正常,这个的话还是有兼容性问题

3.禁止删除变量

1
2
var a;
delete a;

混杂模式:删除变量会默认返回false,但是不会有提示
严格模式:报错->不能删除

4.函数不能有重名参数

1
2
3
4
5
function fun(a,a){
console.log(a); //2
console.log(arguments); //[1,2]
}
fun(1,2);

混杂模式:同名参数会后面的值会覆盖前面的值,要取得原始的值可以通过arguments来获取
严格模式:报错->不能有重名的参数

5.arguments对象的限制

1
2
3
4
5
6
7
8
9
10
11
12
function fun(a,b){
// 混杂模式:严格模式
console.log(a); //11
console.log(arguments[0]); //11
a = 8;
console.log(a); //88
console.log(arguments[0]); //81
arguments[0] = 6;
console.log(a); //68
console.log(arguments[0]); //66
}
fun(1,2);

混杂模式:参数名跟arguments对应,两者其中一个改变另一个会跟着改变
严格模式:一开始arguments获取参数值,之后参数名跟arguments互不影响

6.函数声明必须在顶层

1
2
3
4
5
6
7
if(true){
function fun(){
console.log('123');
}
fun();
}
fun();

混杂模式:函数可以在语句块中声明,而且函数都为全局函数
谷歌严格模式:语句块内为块作用域,内部声明的函数可以在内部调用,外部调用会提示函数没有声明
IE严格模式:报错->语句块中不能声明函数

7.eval作用域

1
2
eval("var k = 9;console.log(k)");
console.log(k);

混杂模式:eval中声明的变量会变成全局变量
严格模式:eval内为一个作用域,内部声明的变量外部不能访问

8.禁用with

1
2
3
4
5
6
7
var o = {
a:0,
b:1
}
with(o){
console.log(a);
}

混杂模式:能够使用with,并且with内部访问a为o的属性
严格模式:报错->严格模式不能使用with

9.this

1
2
3
4
5
6
function fun(){
return this;
}
console.log(fun());
console.log(fun.apply(2));
console.log(fun.apply('123'));

混杂模式:函数this默认指向window,通过apply指定对象无论传入的是什么都会转变成相应的对象,如:2->Number{}
严格模式:函数this默认为undefined,通过apply指定的对象传入的是什么就是什么,没有改变
ps:使用构造函数时,如果忘记加new,那么this默认undefined,所以为this添加属性时会报错

10.禁止函数内部遍历调用栈

1
2
3
4
5
6
7
8
9
function fun(){
console.log(arguments.callee);
console.log(fun.caller);
console.log(fun.arguments);
}
function fun2(){
fun();
}
fun2();

混杂模式:arguments.callee会指向该函数、fun.caller会指向调用该函数的函数、fun.arguments会指向函数参数数组
严格模式:报错->callee、caller、arguments在严格模式下是禁用的

11.八进制

1
console.log(012);

混杂模式:012为八进制,会输出10
严格模式:报错->严格模式下不允许八进制

小练习:parseInt(‘012a’)的值是多少?

tips:
1.parseInt没有第二个参数默认10进制
2.IE低版本会自动识别8进制
3.虽然ES5不允许parseInt传入的字符窗为八进制的字符,但是现在很多浏览器没有实现它,所以现在在大部分浏览器上这样写是没有问题的,当然要把这个字符串当成8进制就要自己加第二个参数啦