尤大大说我的代码全部不加分号 | 重学JS

点击上方关注 前端技术江湖,一起学习,天天进步

4df6d59c9291febdc1a84028b02e0079.png

前言

  • 上篇写的想写好面向对象的代码,这篇一定要看 | 重学JS[3]提到的匿名函数提到的分号引起的报错,有猿友感兴趣私信,接下来看看一个分号引起的一系列思考。


面试官:知道什么叫类吗?
我这个人很实在,工作努力,不知道什么叫累(类)。

贴一张尤大大17年在知乎说的一段话。

964580bf0d948ec30a2d3c1f6e440039.png
74fe6d709d23448795ecc673a328c1db_tplv-k3u1fbpfcp-watermark.jpg
5225673529ebfb3a35c76a54c646e28c.png
52abedf205f04c778fa909291df41785_tplv-k3u1fbpfcp-watermark.jpg

被网友笑死。

什么情况下不加分号必报错?

其实只要我们避免不加分号,程序能正常跑通,那我们就没必要加上分号啦。

个人认为不加分号代码可读性、可观性有所提升。

那么问题来了,什么情况下不加分号会有问题?

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

15819cef5e1f8f3ac0cdbce686c55f52.png
4081634269-5e55ce8f695cc_articlex.jpg

附上webpack删除项目全部输出console.log

config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
复制代码

那现在为什么不用加分号了?

那是因为人家插件(babel)帮我们处理好了,所以我们才高枕无忧开发。

最后

尤大大说:我的Vue代码全部不带分号,其实加不加分号也只是编码风格问题,不必引起一场口水战。

原文链接

juejin.cn/post/700352…[12]

关于本文

作者:git-Dignity

https://juejin.cn/post/7003522601523871775

The End

欢迎自荐投稿到《前端技术江湖》,如果你觉得这篇内容对你挺有启发,记得点个 「在看」

点个『在看』支持下 7994f36ea9db7a5415190fe5821c3061.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值