一、理解严格模式
1.1、JavaScript 是一门弱类型语言,为了防止导致不可预测的错误,增加代码规范,为了使编写的代码变得更合理、更安全、更严谨,ECAMscript5 提出了"严格模式",处于严格模式下运行的 JavaScript 代码会遵循更加苛刻的条件。
1.2、关键字:
"use strict";
1.3、关键字说明:
1、注意区分大小写,必须全部都是小写的
2、注意空格,整个字符串总共10个字符
3、单引号和双引号无所谓,但是需要有引号
4、必须写在作用域的最顶部,注意其具体的位置
5、可以加分号,也可以不加,但是必须是一个字符串
// 正确示例
“use strict”;
// 错误示例
"USE strict";
" use strict ";
"("USE strict").toLowerCase();"
1.4、兼容性
IE10+的浏览器 及其他主流浏览器均支持严格模式。
1.5、开发中使用吗?
问:平时开发使用严格模式吗?
答:平时使用vue工程化项目,其实已经在使用严格模式了。
二、如何开启严格模式
2.1、整个文件开启严格模式
我们平常写代码的时候可能没太注意严格模式和非严格模式,默认情况下,我们编写的 js 代码都是非严格模式的,想要开启严格模式,我们需要在规定的地方添加'use strict'关键词。
<script>
"use strict";
console.log("严格模式");
</script>
<script>
console.log("非严格模式")
</script>
2.2、单个函数开启严格模式
除了给整个脚本文件添加严格模式外,我们还可以只针对某个函数开启严格模式,我们只需要将"use strict"关键词放在函数体的第一行即可。
function strict() {
"use strict";
return "严格模式";
}
function notStrict() {
return "正常模式";
}
三、严格模式的特点
在变量中、在对象中、在函数中。
3.1、变量
3.1.1、严格模式下变量使用前必须要声明
非严格模式
<script>
snow = 'snowball'
console.log(snow)
</script>
浏览器正常打印没有报错
严格模式
<script>
"use strict"
snow = "snowball"
console.log('snow')
</script>
浏览器报错,提示:snow is not defined
3.1.2、严格模式下不能使用delete删除变量
非严格模式
<script>
// 变量
snow = "snowball"
delete window.snow
console.log(snow)
</script>
snow is not defined 说明已经删除
严格模式
<script>
// 变量
"use strict"
snow = "snowball"
delete snow
console.log(snow)
</script>
3.1.3、无法使用关键词作为变量名
非严格模式
<script>
// 变量
//"use strict"
let implements= "snowball"
console.log(implements)
</script>
严格模式
<script>
// 变量
"use strict"
let implements= "snowball"
console.log(implements)
</script>
3.2、对象
属性描述符,出现不当操作的时候(静默失败,出现报错)
3.2.1、对象属性操作会更加严格
非严格模式
<script>
//"use strict";
let obj = {}
Object.defineProperty(obj, "name", { value: 'snow', writable: false });
obj.name = "snowball"
console.log(obj);
</script>
严格模式
<script>
"use strict";
let obj = {}
Object.defineProperty(obj, "name", { value: 'snow', writable: false });
obj.name = "snowball"
console.log(obj);
</script>
非严格模式
<script>
let obj = {}
Object.preventExtensions(obj); // 禁止添加属性
obj.name = "snow"
console.log(obj);
</script>
严格模式
<script>
"use strict";
let obj = {}
Object.preventExtensions(obj); // 禁止添加属性
obj.name = "snow"
console.log(obj);
</script>
3.3、函数
3.3.1、函数参数不能有重名函数
正常情况
//"use strict";
function setName(name, name2) {
console.log(name, name2)
}
setName('snow');
非严格模式,参数相同
<script>
//"use strict";
function setName(name, name) {
console.log(name, name)
}
setName('snow');
</script>
严格模式
<script>
"use strict";
function setName(name, name) {
console.log(name, name)
}
setName('snow');
</script>
3.3.2、函数arguments有限制
3.3.2.1、无法修改arguments
非严格模式
<script>
//"use strict";
function setName(name){
arguments = 'snowball'
console.log(arguments)
}
setName('snow');
</script>
严格模式
<script>
"use strict";
function setName(name){
arguments = 'snowball'
console.log(arguments)
}
setName('snow');
</script>
3.3.2.2、不再追踪参数变化
非严格模式
<script>
//"use strict";
function setName(name){
arguments = 'snowball'
console.log(name);
console.log(arguments)
}
setName('snow');
</script>
严格模式
<script>
"use strict";
function setName(name){
arguments = 'snowball'
console.log(name);
console.log(arguments)
}
setName('snow');
</script>
3.3.2.3、禁止使用arguments.callee
非严格模式
<script>
//"use strict";
function setName(name){
arguments.callee();
}
setName('snow'); // 正常调用,只不过要考虑内存溢出问题
</script>
严格模式
<script>
"use strict";
function setName(name){
arguments.callee();
}
setName('snow');
</script>
3.3.3、函数必须声明在顶层
其实这和 JavaScript 中的块级作用域是比较相符的,在严格模式下,我们不能把函数声明在 if 或者 for 语句中。
非严格模式
<script>
// "use strict";
if (true) {
function setName(name){
console.log(name)
}
}
setName('snow');
</script>
严格模式
<script>
"use strict";
if (true) {
function setName(name){
console.log(name)
}
}
setName('snow');
</script>
3.4、禁止使用eval()
eval 一直都是备受大家争议的,它可以直接执行一段代码,这会导致非常多的问题,所以在严格模式下直接禁用它了。
非严格模式
<script>
//"use strict";
function setName(name){
eval('myname = "snowball"')
console.log(myname)
}
setName('snow');
</script>
严格模式
<script>
"use strict";
function setName(name){
eval('myname = "snowball"')
console.log(myname)
}
setName('snow');
</script>
3.5、禁止使用width语句
with 语句主要用来扩展作用域链,它也备受争议,因为它无法在编译时确定属性到底属于哪个对象,所以我们目前是不建议使用它,所以严格模式下也直接禁止使用它了。
非严格模式
<script>
//"use strict";
let obj = {
name: 'snow'
}
with (obj) {
name = 'snowball';
}
console.log(obj);
</script>
严格模式
<script>
"use strict";
let obj = {
name: 'snow'
}
with (obj) {
name = 'snowball';
}
console.log(obj);
</script>
3.6、this无法指向全局
使用 bind、apply 等方法修改 this 指向,但是当我们没有显示执行 this 指向时,this 默认会指向全局,在严格模式下这是不允许的。
非严格模式
<script>
// "use strict";
function setName() {
console.log('this:' this)
}
setName.call(null)
</script>
严格模式
<script>
"use strict";
function setName() {
console.log('this:' this)
}
setName.call(null)
</script>
3.7、禁止八进制写法
在正常模式下,如果某个整数的第一位是 0,那么表示该数是八进制数,会自动进行转换,但是在严格模式下无法进行有效转换。
非严格模式
<script>
//"use strict";
let snow = 0100
console.log(snow)
</script>
严格模式
<script>
"use strict";
let snow = 0100
console.log(snow)
</script>
四、再次理解严格模式
严格模式给我们带来了规范,但是同时也给我们带来了一些不便,但是为了未来的发展,我们最好还是按照严格模式的要求来,这样可以最大程度的减少我们出错的机率,也能够让我们的程序能够走得更远。
五、过程记录
记录一:
1、创建项目strict/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
<head>
<body>
// 变量
"use strict"
snow = "snowball"
console.log(snow)
</body>
</html>
2、http-server启动项目的服务
3、启动后访问页面
4、访问成功
记录二:
vue2项目,,没有开启严格模式也会报错,,
nuxt3+vue3+ts项目,,没有开启严格模式也会报错,,
// vue2项目
let snow = 0100
console.log(snow)
// vue3 + ts项目
let snow = 0100
console.log(snow)
这说明,vue工程化项目,默认已经开启了严格模式,其实是这样的开启了。
如果不想开启,可以在项目中进行配置。
五、欢迎交流指正、关注我、一起学习。
参考链接:
前端 - vue中mounted中 或者说vue这个框架默认是严格模式? - SegmentFault 思否
【全网首发:完结】JS 中的严格模式【 经典前端面试题 】_哔哩哔哩_bilibili