markdown JS严格模式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown JS严格模式相关的知识,希望对你有一定的参考价值。
## 概述
严格模式(strict mode)是ECMAScript5退出的一套相对正常运行模式的模式,主要是为了让js在更加严格的条件下运行。
增加严格模式的主要目的是:
* 消除js语法的不合理、不严谨的地方,减少怪异的使用行为;
* 消除代码运行一些不安全的地方;
* 提高编译器效率,增加运行速度;
* 为未来新版本做铺垫;
> 包括IE10在内的主流浏览器已经支持严格模式,参见[支持情况](https://caniuse.com/#search=strict%20mode)。
## 使用方式
### 针对整个脚本文件
将“use strict”放在脚本的第一行(前面产生实际运行结果就行),则整个脚本将会在严格模式下运行,如果不在第一行则失效,代码将以正常模式运行,所以做jsbundle的时候要注意这个问题。
```js
'use strict';
function func(){}
```
```html
<script>
'use strict';
function func1(){}
</script>
<script>
function func2(){}
</script>
```
> PS: 上面这段,在第一个script块中会以严格模式运行,后面这个会以正常模式运行。
### 针对函数
将"use strict"放在函数体的第一行,整个函数会以严格模式运行。
```js
function func() {
'use strict';
alert('hello');
}
```
### 变通方法
为了解决上面第一种方式js 合并的问题,可以用匿名函数包裹脚本的方式解决。
```js
(function(){
'use strict';
function func() {}
})()
```
## 主要内容
#### 全局变量显式申明
在正常模式中,如果变量没有申明就赋值,默认为全局变量,严格模式不允许这种赋值;
```js
'use strict';
v = 100; //报错
for (i = 1; i < 10; i++) {} //报错
```
#### 静态绑定
js允许静态绑定,即属性或方法属于哪个对象,不在编译阶段确定,而是在运行时确定。严格模式对动态绑定做了限制,有些情况下只能用静态绑定,这样可以提高编译效率,提升代码可读性。
* 禁止使用with语句
```js
'use strict';
var v = 2;
with (o) { //语法错误
alert(v);
}
```
* 创设eval作用域
正常模式下,js有两种作用域,全局作用域和函数作用域,eval的作用域根据它所处的位置是全局作用域还是函数作用域来决定,严格模式新增了一个eval作用域。
```js
'use strict';
var v = 2;
console.log(eval("var v = 5; v")); //5
console.log(v) //2
```
### 增强安全措施
* 禁止this对象指向全局对象
```js
function() {
return !this; //返回fasle,因为this指向全局对象
}
function() {
'use strict';
return !this; //返回true,因为this是undefined
}
```
因此在使用构造函数时往了加new 会报错
```js
'use strict';
function f() {
this.name = 'hello'
}
f(); //报错this未定义
```
* 禁止在调用内遍历调用栈
```js
function func() {
'use strict';
func.caller; //报错
func.callee; //报错
func.arguments; //报错
}
func();
```
### 禁止删除变量
严格模式下不允许删除变量,只有configurable为true的属性才可以删除。
```js
'use strict';
var i = 10;
delete i; //报错
var obj = Object.create(null, {
x: {
value: 1,
configurable: true
}
});
delete obj.x //删除成功
```
### 显式报错
正常模式下对于只读变量进行复制,不会报错,只会默默失效,在严格模式下回报错。
```js
"use strict";
var o = {};
Object.defineProperty(o, "v", { value: 1, writable: false });
o.v = 2; // 报错
```
严格模式下,对一个使用getter方法读取的属性进行赋值,会报错。
```js
"use strict";
var o = {
get v() { return 1; }
};
o.v = 2; // 报错
```
严格模式下,对禁止扩展的对象添加新属性,会报错。
```js
"use strict";
var o = {};
Object.preventExtensions(o);
o.v = 1; // 报错
```
严格模式下,删除一个不可删除的属性,会报错。
```js
'use strict';
var obj = {};
delete obj.prototype; //报错
```
### 重名错误
* 对象不能有重名属性,在正常模式下,后面声明的属性会覆盖前面的属性;
```js
'use strict';
var obj = {
a: 1,
a: 2
} //会报语法错误
```
* 函数不能有重名参数,在正常模式下,可以通过arguments[i],来获取不同的参数;
```js
'use strict';
function func(a, a, b) {
} //会报语法错误
```
### 禁止8进制写法
正常模式下数字以0开头表面为八进制数,严格模式禁止这种表达方式,数字前面为0会报错。
```js
'use strict';
var num = 0100; //报错
```
### arguments限制
严格模式对arguments的使用做了很多限制。
* 不能对arguments赋值;
```js
'use strict';
arguments++; //报错
function arguments() {} //报错
try {} catch(arguments) {} //报错
```
* 不能追踪arguments变化;
```js
//正常模式下
function func(a) {
a = 2;
return [a, arguments[0]];
}
func(1); //返回[2,2]
//严格模式下
'use strict'
function func(a) {
a = 2;
return [a, arguments[0]];
}
func(1); //返回[2,1]
```
* 禁止使用arguments.callee;
```js
'use strict';
function func() {
return arguments.callee;
}
func(); //报错
```
> function.caller也是禁用的;
### 函数必须声明在顶层
由于当时考虑到js会引入块级作用域,所以在严格模式下,规定,函数声明必须在全局或者函数作用域的顶层进行声明。
```js
'use strict';
if (true) {
function func() {} //语法错误
}
for(var i = 0; i < 10; i++) {
function func() {} //语法错误
}
```
###保留字
严格模式下增加了新的保留字:implements, interface, let, package, private, protected, public, static, yield。此外,ECMAscript第五版本身还规定了另一些保留字(class, enum, export, extends, import, super),以及各大浏览器自行增加的const保留字,也是不能作为变量名的。
## 参考
* http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
以上是关于markdown JS严格模式的主要内容,如果未能解决你的问题,请参考以下文章