一、严格模式

一、严格模式

ES5拓展了严格模式,是我们的代码更加的安全可靠

在之前书写代码都是处于正常模式下

  • 正常模式下,定义一个变量可以不使用 var ,严格模式下是不允许的

  • 正常模式下,可以使用八进制,严格模式下不允许

  • 正常模式下,可以使用arguments.callee,严格模式下不允许

1.1 开启严格模式

使用方式:“use strict”

加入“use strict”之后,如果认识它的浏览器就会自动开启严格模式;如果不认识它的浏览器也只是把它当作一个字符串定义,不会影响后续代码

开启严格模式之后,就必须按照严格模式的代码规范书写代码

在js代码第一行加入“use strict”,此时代码将处于“全局严格模式”

在某个函数的第一行加入“use strict”,当函数执行的时候,此时函数处于“局部严格模式”

举例:

在正常模式下:

1
2
3
4
5
// 使用 var 定义变量
var a = 10;

// 不使用 var
b = 20;

U1ApOf.png

在严格模式下:

1
2
3
4
5
6
7
// 开启严格模式
"use strict"
// 使用 var 定义变量
var c = 30;

// 不使用 var 在严格模式下是不允许的
d = 40;

会报错:

U1AnXV.png

1
2
3
4
5
6
7
8
// 使用 var 定义变量
var e = 50;

// 不使用 var 在严格模式下是不允许的
f = 60;
// 在开启严格模式之前仍处于正常模式
// 开启严格模式
"use strict"

U1A8h9.png

局部严格模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 局部严格模式
// 定义函数
function localStrict(){
// 开启严格模式
"use strict"
// 定义变量
var a = 10;
// b = 11;
}
localStrict(); // 只有调用函数才会报错,不调用,不会报错

// 不使用 var 定义变量
c = 20;

U1AanK.png

1.2 在严格模式下定义变量

在严格模式下定义变量,必须使用var声明

允许:

var a = 10;

不允许:

b = 20;

举例:

1
2
3
4
5
6
7
8
// 开启严格模式
"use strict"
// 使用 var 定义变量
var a = 10;

// 不使用 var 定义变量
// 在严格模式下不允许 不使用 var
b = 20;

U1ABAe.png

1.3 八进制

在js中有三种进制:

8 进制 10 进制 16 进制

默认是 10 进制

以 0 开头是 8 进制

以 0x,或ox开头的是 16 进制

允许:

1
2
var num = 16;
var num1 = 0xff;

不允许:

1
var num = 011;

举例:

在正常模式下:

1
2
3
4
5
// 定义变量
var num = 16;
var num1 = 0xff;

var num2 = 011;

输出:

U1Arhd.png

在严格模式下:

1
2
3
4
5
6
7
// 开启严格模式
"use strict"
// 定义变量
var num = 16;
var num1 = 0xff;

var num2 = 011;

会报错:

U1Acct.png

1.4 arguments.callee

代码写的越“具体”,越能提升性能

arguments.callee 在编译阶段是无法解析出来,至于当执行到的时候才能确定下来,所以就无从提升性能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 安全类
function People(name, age, sex){
// 判断 this 指向
if (this instanceof People){
this.name = name;
this.age = age;
this.sex = sex;
} else {
// 没有使用 new 调用
return new People(name, age, sex);
}
}

// 实例化对象
var p = new People("小明", 12, "男");

var p1 = People("小龙", 12, "男");

U1A5NQ.png

在正常模式下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 安全类
function People(name, age, sex){
// 判断 this 指向
if (this instanceof arguments.callee){
this.name = name;
this.age = age;
this.sex = sex;
} else {
// 没有使用 new 调用
return new arguments.callee(name, age, sex);
}
}

// 实例化对象
var p = new People("小明", 12, "男");

var p1 = People("小龙", 12, "男");

U1A73n.png

在严格模式下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 开启严格模式
"use strict"
// 安全类
function People(name, age, sex){
// 判断 this 指向
if (this instanceof arguments.callee){
this.name = name;
this.age = age;
this.sex = sex;
} else {
// 没有使用 new 调用
return new arguments.callee(name, age, sex);
}
}

// 实例化对象
var p = new People("小明", 12, "男");

var p1 = People("小龙", 12, "男");

会报错:

U1ALuV.png

1.5 使用delete

使用delete可以删除对象中的属性

  • 若果要删除一个变量:

    • 在正常模式下,可以执行成功,不会删除成功,但是不会报错

    • 在严格模式下,会报错

在正常模式下:

1
2
3
4
5
6
7
// 定义全局变量
var a = 10;
window.b = 20;

// 删除变量
console.log(delete a);
console.log(delete b);

U1EpC9.png

在严格模式下:

1
2
3
4
5
6
7
8
9
// 开启严格模式
"use strict"
// 定义全局变量
var a = 10;
window.b = 20;

// 删除变量
console.log(delete a);
console.log(delete b);

会报错:

U1EAHO.png

1.6 使用保留字定义变量

  • 正常模式下,可以使用保留字定义变量

  • 严格模式下,不能使用保留字定义变量

在正常模式下:

1
2
// 使用保留字
var public = "呵呵";

U1EnCd.png

在严格模式下:

1
2
3
4
// 开启严格模式
"use strict"
// 使用保留字
var public = "呵呵";

会报错:

U1Ea2n.png

1.7 eval

eval是一个函数,可以将字符串当作代码执行,但是会污染全局作用域

在严格模式下是不允许使用的,所以可以避免污染全局作用域

在正常模式下:

1
2
3
4
5
6
7
8
9
// 定义变量
var strcode = "var a = 10";

// eval接收一个参数就是字符串,执行结果就是字符串代码
// 当eval执行的时候, a 真的被定义出来了
eval(strcode);

// 等价方法
// var a = 10;

U1EhKx.png

在严格模式下:

1
2
3
4
// 开启严格模式
"use strict"
var strcode = "var a = 10";
eval(strcode);

输入 a 会报错:

U1EoVO.png

严格模式下,检测eval的方式:

1
2
3
4
5
6
7
8
// 开启严格模式
"use strict"
var strcode = "var a = 10";
eval(strcode);

// 这只是告诉大家,严格模式检测 eval 的方式,并不是说要这样用
var s = eval;
s(strcode);

U1EOxI.png

1.8 with

with是一个语法,在代码执行的时候,会改变作用域

1
2
3
with(target){
console.log(a); // 如果target中存在a属性,那么会优先输出a,如果没有,那么会沿着词法作用域一直往上查找
}

正常模式下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 定义对象
var obj = {
a: 1,
b: 2
}

var a = 10;
var b = 20;

// 使用 with
with (obj){
// 此时 obj 中, 存在 a 和 b ,那么会优先输出 obj 中的 a 和 b
console.log(a);
console.log(b);
// 此时 obj 中存在 a 属性, 所以优先改变 obj 中的 a
a = 111;
// obj 中没有 c ,所以会将 c 添加在全局中,会污染全局作用域中的变量
c = 123;
}

U1VMi4.png

严格模式下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 开启严格模式
"use strict"
// 定义对象
var obj = {
a: 1,
b: 2
}

var a = 10;
var b = 20;

// 使用 with
with (obj){
// 此时 obj 中, 存在 a 和 b ,那么会优先输出 obj 中的 a 和 b
console.log(a);
console.log(b);
// 此时 obj 中存在 a 属性, 所以优先改变 obj 中的 a
a = 111;
// obj 中没有 c ,所以会将 c 添加在全局中,会污染全局作用域中的变量
c = 123;
}

会报错:

U1VJL6.png

1.9 变量名称

  • 在正常模式下,在一个对象中定义属性可以是同名的

  • 在严格模式下,不会报错,只是浏览器检测不出来

举例:

正常模式下:

1
2
3
4
5
6
// 定义对象
var obj = {
a: 1,
a: 2
}
console.log(obj.a); // 2 后面的覆盖前面的

U1VNdO.png

严格模式下:

1
2
3
4
5
6
7
8
// 开启严格模式
"use strict"
// 定义对象
var obj = {
a: 1,
a: 2
}
console.log(obj.a); // 2 后面的覆盖前面的

U1VDSA.png

注:没有区别,不是严格模式没有开启,只是浏览器没有实现

1.10 全局函数作用域

  • 在全局函数作用域中的this指向window,会污染全局作用域

  • 在严格模式下,全局作用域中的this变为undefined,就可以避免对全局作用域的污染

举例:

正常模式下:

1
2
3
4
5
6
7
8
9
10
// 定义函数
function fun(){
var b = 10;
console.log(b);
// 全局函数作用域
console.log(this);
// 添加属性
this.color = "red";
}
fun();

U1Vcef.png

严格模式下:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 开启严格模式
"use strict"

// 定义函数
function fun(){
var b = 10;
console.log(b);
// 全局函数作用域
console.log(this);
// 添加属性
this.color = "red";
}
fun();

会报错,this指向变为undefined:

U1VzlR.png

1.11 函数参数

  • 正常模式下,定义函数的参数可以使同名的,但是后面的会覆盖前面的

  • 严格模式下,则是不允许的

在正常模式下:

1
2
3
4
5
// 定义函数
function fun(color, color){
console.log(color); // blue
}
fun("red", "blue");

在严格模式下:

1
2
3
4
5
6
7
// 开启严格模式
"use strict"
// 定义函数
function fun(color, color){
console.log(color);
}
fun("red", "blue");

会报错:

U1ZZpd.png

点击查看

本文标题:一、严格模式

文章作者:Mango

发布时间:2020年07月14日 - 12:58:27

最后更新:2020年07月14日 - 13:27:10

原始链接:https://mango185.github.io/post/f5165bd5.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------------本文结束 感谢您的阅读-------------------