严格模式

      最近又重温了一下犀牛书,想对严格模式下的语言规范进行一下梳理和总结。“use strict” 是 ES5 引入的一条指令,它只能出现在脚本代码的开始或者函数体的开始、任何实体语句之前。使用”use strict”令的目的是说明(脚本或函数中)后续的代码将会解析为严格代码。严格模式是一种特殊的执行模式,它修复了部分语言上的不足,提供更强的错误检查,并增强安全性。不建议在整个脚本中使用严格模式,建议按照一个个函数去开启严格模式。避免合并脚本带来的问题

1
2
3
function A(){
“use strict”
}
1
2
3
4
"use strict"
function A(){

}

不允许用with语句

1
2
3
4
5
6
!function(){}(
"use strict";
with({x:1}){
console.log(x);
};
);

报错:语法错误 SyntaxError

不允许未声明的变量被赋值

1
2
3
4
5
!function(){
"use strict";
x = 1;
console.log(window.x);
}()

报错:引用错误 ReferenceError(在作用域中找不到),在非严格模式下,这种隐式声明的全局变量的方法是给全局对象新增加一个新属性,但是在严格模式下,所有的变量都要先声明。

调用的函数(不是方法)中this指的是 undefined

1
2
3
4
5
function A(){
"use strict";
return this;
}
A() === undefined; //true
1
2
3
4
function A(){
return this;
}
A() === window

一般函数中this指的是 window,严格模式下,this指的是 undefined

使用applycallbind时,当传入的参数为’null 或 undefined’时,this 指向‘null 或 undefined’

1
2
3
4
5
6
7
!function(){
"use strict";
function A(){return this};
console.log(apply(null)); //null
console.log(call(undefined)); //undefined
console.log(bind(null)); //null
}()
1
2
3
4
5
6
!function(){
function A(){return this};
console.log(apply(null)); //window
console.log(call(undefined)); //window
console.log(bind(null)); //window
}()

不允许给只读属性赋值和不可扩展的对象创建新成员

只读属性

1
2
3
4
5
6
7
8
9
!function(){
"use strict";
var obj = {
get x(){
return 8;
};
};
obj.x = 6;
}()

报错:类型错误 TypeError,在非严格模式下,只是简单的操作失败

不可扩展的对象

1
2
3
4
5
6
!function(){
"use strict";
var obj = { name:'Lucy' };
Object.preventExtensions(obj);
obj.age = 17;
}()

报错:类型错误 TypeError,在非严格模式下,只是简单的操作失败

eval 具有独立的作用域

1
2
3
4
5
!function(){
"use strict"
eval('var age = 15;');
console.log(typeof age); //undefined
}()
1
2
3
4
!function(){
eval('var age = 15;');
console.log(typeof age); //number
}()

arguments 变为静态的参数副本

1
2
3
4
5
!function(x){
"use strict";
arguments[0] = 10;
console.log(x); //1
}(1)
1
2
3
4
!function(x){
arguments[0] = 10;
console.log(x); //10
}(1)

严格模式下,argument 不可被修改,但是我们可以通过传对象的方式修改

1
2
3
4
5
!function(a){
"use strict";
arguments[0].x =10;
console.log(a.x); //10
}({x:1})

不能删除非法的标识符(比如变量、函数、函数参数)

1
2
3
4
!function(a){
"use strict";
delete a;
}(1)

报错:语法错误 SyntaxError

1
2
3
!function(a){
console.log(delete a); //false
}()

在非严格模式下,返回 false,无意义但不会报错

不能删除不可配置的属性

1
2
3
4
5
6
7
8
!function(a){
"use strict";
var obj = {};
Object.defineProperty(obj,'a',{
configurable:false
});
delete obj.a;
}(1)

报错:类型错误 TypeError

1
2
3
4
5
6
7
!function(a){
var obj = {};
Object.defineProperty(obj,'a',{
configurable:false
});
console.log(delete obj.a); //false
}(1)

在非严格模式下,delete 表达式操作失败,并返回 false

对象字面量重复属性报错

1
2
3
4
5
!function(){
"use strict";
var obj={x:1,x:2};
console.log(obj.x);
}()

报错:严格模式下报语法错误 SyntaxError

1
2
3
4
!function(){
var obj={x:1,x:2};
console.log(obj.x); //2
}()

非严格模式下最后一个重名对象将覆盖之前的

函数参数名重复报错

1
2
3
4
!function(x,x,y){
"use strict";
console.log(x+y);
}(1,2,3)

报错:严格模式下报语法错误 SyntaxError

1
2
3
4
!function(x,x,y){
"use strict";
console.log(x+y); //5
}(1,2,3)

非严格模式下,最后一个重名参数会覆盖之前的重名参数

禁止八进制字面量

1
2
3
4
!function(){
"use strict";
console.log(0123);
}()

报错:严格模式下报语法错误 SyntaxError

1
2
3
!function(){
console.log(0123); //83
}()

eval、arguments 变为关键字,不能作为变量、函数名

1
2
3
4
!function(){
"use strict";
function eval(){};
}()

报错:严格模式下报语法错误 SyntaxError

1
2
3
4
!function(){
function eval(){};
console.log(eval); //function eval(){}
}()

禁用arguments.callerarguments.callee

Copyright ©2019 guowj All Rights Reserved.

访客数 : | 访问量 :