非严格模式(Sloppy mode)和严格模式(Strict mode)
其实两个都是Javascript
的执行环境,但它们在对语言的某些特性和行为上会有所不同。
1.怎么用?
- 默认情况下,Javascript在非严格模式下运行。
- 在脚本或函数的顶部添加
"use strict";
我们就进入了严格模式。 - 比如说:
我们可以直接在脚本中把"use strict";
放在所有语句之前,进入严格模式。或者函数添加"use strict";
进入严格模式
function strict() {
'use strict';
var value = "Hi! I'm a strict mode script!";
console.log(value);
}
2.非严格模式支持哪些行为?
- 允许变量在声明之前就被使用(导致隐式全局变量)
this
就算没有绑定具体的对象,也会指向全局对象- 函数参数可以重名
- 删除不可配置的属性
// 变量未声明之前就被使用
data = 5;
console.log(data); //输出的结果为 5
// this指向全局对象
console.log(this === window); // 在浏览器中,非严格模式下输出 true
// 函数参数可以重名
function foo(a, a, b) {
console.log(a + a + b);
}
// 删除不可配置的属性
var obj = {};
Object.defineProperty(obj, 'name', { value: 'Alice', configurable: false });
delete obj.name; // 在非严格模式下,尽管属性是不可配置的,但不会报错,只是删除操作无效
console.log('name' in obj); // 输出 true
3.严格模式支持哪些行为?
- 不允许变量在声明之前就被使用
this
必须要绑定具体的对象- 禁止使用删除操作符删除不可配置属性
- 函数内
this
的默认值为undefined
- 禁止使用八进制字面量
// 不允许变量在声明之前就被使用
'use strict';
y = 10;
console.log(y);// 抛出错误:ReferenceError: y is not defined
// 全局作用域下的this是undefined
'use strict';
console.log(this === undefined); // 在严格模式下,输出 true
// 禁止删除不可配置的属性
'use strict';
var obj = {};
Object.defineProperty(obj, 'name', { value: 'Alice', configurable: false });
delete obj.name; // 在严格模式下,会抛出错误:Uncaught TypeError: Cannot delete property 'name' of #<Object>
// 函数内this的默认值为undefined
'use strict';
function testThis() {
console.log(this);
}
testThis(); // 输出 undefined
// 禁止使用八进制字面量
'use strict';
var num = 070; // 抛出错误:SyntaxError: Octal literals are not allowed in strict mode.
4.非严格模式和严格模式的优势和限制
- 非严格模式下,代码的兼容性更好,使用起来更加灵活,但可能引起问题的特性(比如变量未声明就被使用)也会存在。
- 严格模式下,代码的兼容性更差,但同时也更安全,提高了代码的质量。
5.React、Vue
前端框架使用严格模式
// React使用严格模式
// 通常直接在index.js文件中
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// Vue使用严格模式
// 通常直接在main.js文件中
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
Vue.config.devtools = true
Vue.config.strict = process.env.NODE_ENV !== 'production'
new Vue({
render: h => h(App),
}).$mount('#app')