前言
在线音乐[1]戳我呀!
音乐博客源码[2]上线啦!
上篇写的想写好面向对象的代码,这篇一定要看 | 重学JS[3]提到的匿名函数提到的分号引起的报错,有猿友感兴趣私信,接下来看看一个分号引起的一系列思考。
面试官:知道什么叫类吗?
我这个人很实在,工作努力,不知道什么叫累(类)。
贴一张尤大大17年在知乎说的一段话。
被网友笑死。
什么情况下不加分号必报错?
其实只要我们避免不加分号,程序能正常跑通,那我们就没必要加上分号啦。
个人认为不加分号代码可读性、可观性有所提升。
那么问题来了,什么情况下不加分号会有问题?
1. 小括号开头的前一条语句
这里我们可以拿一下上一篇写的想写好面向对象的代码,这篇一定要看 | 重学JS[4]里面的一个例子。
var a = 4
console.log(a)
;(function () {
function load () {
console.log('添加一个事件处理程序到 load 事件')
}
window.$ = function () { // 向外暴露一个全局函数
return {
load: load
}
}
})()
复制代码
想说的一点是,为什么匿名函数前面要加分号;
假设:如果不加分号,程序最终编译成这样子:
var a = 4
console.log(a)(function () {...}
复制代码
结果就会报错:Uncaught TypeError: console.log(...) is not a function
Why?
那是因为匿名函数是以括号()为开头,对于程序括号()代表函数执行,那前面应该就有函数名,编译后空格去掉就console.log(a)(...)
,自然报错。
这也是为什么JS语句后要加分号的原因。
那我不想在每条语句(console.log(a)
)后都加分号怎么办?
就需要在匿名函数前加分号,后面不加就前面加。
再来一条例子看看:
var a = 4
(function (){
})()
// 程序理解是这样子的:
var a = 4(function (){})()
4后面是括号(),那说明4应该是一个函数,只有函数才加括号执行。
执行4函数,发现4并不是函数,所以报错。
// 浏览器报错:Uncaught TypeError: 4 is not a function
复制代码
这就是小括号开头的前一条语句要加分号。(匿名函数)
2. 中方括号开头的前一条语句
var b = 4
[1, 3].forEach(function () {})
// 程序理解是这样子的:
var b = 4[1, 3].forEach(function () {})
// 4[3] 这是什么语法?
// 自然是undefined。
// 果不其然,浏览器报错:
// Uncaught TypeError: Cannot read properties of undefined (reading 'forEach')
复制代码
当然,解决方法就是在行首加分号。
在JQ时代,为什么总有人喜欢在js文件开头加分号?
;var obj = {};
(function() {
})()
复制代码
那是因为怕js文件合并压缩的时候,会报错,因为不确保其他同事的js文件有没有加分号。(会因为缺少分号,导致语法报错)
压缩的时候,压缩流程是怎样的?
去除多余字符: 空格,换行及注释
一般来说中文会占用更大的空间。
替换掉多余字符后会有什么问题产生呢?
有,比如多行代码压缩到一行时要注意行尾分号。
这就需要通过以下介绍的 AST 来解决。
为什么要压缩变量名?
比如你定义的函数名叫
fun()
,可能会变成a()
为什么?
更好的节省空间。
压缩变量名:变量名,函数名及属性名
当完成代码压缩 (compress) 时,代码的混淆 (mangle) 也捎带完成。(缩短变量的命名也需要 AST 支持)
uglify 在代码压缩中使用到的解析器是 UglifyJS。
// 原始代码
const code = `const a = 3;`
// 通过 UglifyJS 把代码解析为 AST
const ast = UglifyJS.parse(code);
ast.figure_out_scope();
// 转化为一颗更小的 AST 树
compressor = UglifyJS.Compressor();
ast = ast.transform(compressor);
// 再把 AST 转化为代码
code = ast.print_to_string();
复制代码
压缩代码的过程:code -> AST -> (transform)一颗更小的AST -> code
附上webpack删除项目全部输出console.log
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
复制代码
那现在为什么不用加分号了?
那是因为人家插件(babel)帮我们处理好了,所以我们才高枕无忧开发。
最后
尤大大说:我的Vue代码全部不带分号,其实加不加分号也只是编码风格问题,不必引起一场口水战。
以往推荐
老湿说的万物皆对象,你也信?[5]
Vue-Cli3搭建组件库[6]
Vue实现动态路由(和面试官吹项目亮点)[7]
项目中你不知道的Axios骚操作(手写核心原理、兼容性)[8]
VuePress搭建项目组件文档[9]
koa2+vue+nginx部署[10]
vue-typescript-admin-template后台管理系统[11]
原文链接
juejin.cn/post/700352…[12]
关于本文
作者:git-Dignity
https://juejin.cn/post/7003522601523871775
最后
欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿
回复「算法」,加入前端编程源码算法群,每日一道面试题(工作日),第二天瓶子君都会很认真的解答哟!
回复「交流」,吹吹水、聊聊技术、吐吐槽!
回复「阅读」,每日刷刷高质量好文!
如果这篇文章对你有帮助,「在看」是最大的支持
》》面试官也在看的算法资料《《
“在看和转发”就是最大的支持