Vue 为什么要禁用 undefined?

今天我们来伪科普一下——Vue 等开源项目为什么要禁用/限用 undefined?

敏感话题

我们会讨论几个敏感话题,包括但不限于——

  1. 测不准的 undefined 如何引发复合 BUG?
  2. 薛定谔的 undefined 如何造成二义性?
  3. 未定义的 undefined 为何语义不明?

懂得都懂,不懂关注,日后再说~


1. 测不准的 undefined 如何引发复合 BUG?

一般而言,开源项目对 undefined 的使用有两种保守方案:

  • 禁欲系——能且仅能节制地使用 undefined
  • 绝育系——禁用 undefined

举个粒子,Vue 源码就选择用魔法打败魔法——安排黑科技 void 0 重构 undefined

vue-void.png

事实上,直接使用 undefined 也问题不大,毕竟 undefined 表面上还是比较有安全感的。

readonly-desc.gif

猫眼可见,undefined 是一个鲁棒只读的属性,表面上相当靠谱。

虽然 undefined 自己问题不大,但最大的问题在于使用不慎可能会出 BUG。undefined 到底可能整出什么幺蛾子呢?

你知道的,不同于 null 字面量,undefined 并不恒等于 undefined 原始值,比如说祂可以被“作用域链截胡”。

举个粒子,当 undefined 变身成为 bilibili,同事的内心是崩溃的。

bilibili.png

猫眼可见,写做 undefined 变量,读做 'bilbili' 字符串,这样的代码十分反人类。

这里稍微有点违和感。机智如你可能会灵魂拷问,我们前面不是已经证明了 undefined 是不可赋值的只读属性吗?怎么祂喵地一言不合说变就变,又可以赋值了呢?来骗,来偷袭,不讲码德!

这种灵异现象主要跟变量查找的作用域链机制有关。读写变量会遵循“就近原则”优先匹配,先找到谁就匹配谁,就跟同城约会一样,和樱花妹异地恋的优先级肯定不会太高,所以当前局部作用域的优先级高于全局作用域,于是乎 JS 会优先使用当前非全局同名变量 undefined

换而言之,局部的同名变量 undefined 屏蔽(shadow,AKA“遮蔽”)了全局变量 globalThis.undefined

关于作用域链这种“远亲不如近邻”的机制,吾愿赐名为“作用域链截胡”。倘若你不会搓麻将,你也可以命名为“作用域链抢断”。倘若你不会打篮球,那就叫“作用域链拦截”吧。

globalThis.undefined 确实是只读属性。虽然但是,你们重写非全局的 undefined,跟我 globalThis.undefined 有什么关系?

周树人.gif

我们总以为 undefined 短小精悍,但其实 globalThis.undefined 才能扬长避短。

当我们重新定义了 undefinedundefined 就名不副实——名为 undefined,值为任意值。这可能会在团队协作中引发复合 BUG。

所谓“复合 BUG”指的是,单独的代码可以正常工作,但是多人代码集成就出现问题。

举个粒子,常见的复合 BUG 包括但不限于:

  • 命名冲突,比如说 Vue2 的 Mixin 就有这个瑕疵,所以 Vue3 就引入更加灵活的组合式 API
  • 作用域污染,ESM 模块之前也有全局作用域污染的老毛病,所以社区有 CJS 等模块化的轮子,也有 IIFE 等最佳实践
  • 团队协作,Git 等代码版本管理工具的开发冲突

举个粒子,undefined 也可能造成类似的问题。

complex-bug.png

猫眼可见,双方的代码都问题不大,但放在一起就像水遇见钠一般干柴烈火瞬间爆炸。

这里分享一个小众的冷知识,这样的代码被称为“Jenga Code”(积木代码)。

Jenga 是一种派对益智积木玩具,它的规则是,先把那些小木条堆成一个规则的塔,玩家轮流从下面抽出一块来放在最上面,谁放上之后木塔垮掉了,谁就 GG 了。

jenga.gif

积木代码指的是一点点的代码带来了亿点点的 BUG,一行代码搞崩整个项目,码农一句,可怜焦土。

换而言之,这样的代码对于 JS 运行时是“程序正义”的,对于开发者却并非“结果正义”,违和感拉满,可读性和可为维护性十分“赶人”,同事读完欲哭无泪。

所谓“程序正义”指的是——JS 运行时没有“阳”,不会抛出异常,直接挂掉,浏览器承认你的代码 Bug free,问题不大。

祂敢报错吗?祂不敢。虽然但是,无症状感染也是感染。你敢这么写吗?你不敢。除非忍不住,或者想跑路。

举个粒子,“离离原上谱”的“饭圈倒牛奶”事件——

  • 有人鞠躬尽瘁粮食安全
  • 有人精神饥荒疯狂倒奶

这种行为未必违法,但是背德,每次看到只能无视,毕竟语冰有“傻叉恐惧症”。

“程序正义”不代表“结果正义”,代码能 run 不代表符合“甲方肝虚”,不讲码德可能造成业务上的技术负债,将来要重构优化来还债。所谓“前猫拉屎,后人铲屎”大抵也是如此。

综上所述,要警惕测不准的 undefined 在团队开发中造成复合 BUG。


2. 薛定谔的 undefined 如何造成二义性?

除了复合 BUG,undefined 还可能让代码产生二义性。

代码二义性指的是,同一行代码,可能有不同的语义。

举个粒子,JS 的一些代码解读就可能有歧义。

mistake.png

undefined 也可能造成代码二义性,除了上文的变量名不副实之外,还很可能产生精神分裂的割裂感。

举个粒子,代码中存在两个一龙一猪的 undefined

default.png

猫眼可见,undefined 的值并不相同,我只觉得祂们双标。

undefined 变量之所以是 'bilibili' 字符串,是因为作用域链就近屏蔽,cat 变量之所以是 undefined 原始值,是因为已声明未赋值的变量默认使用 undefined 原始值作为缺省值,所以没有使用局部的 undefined 变量。

倘若上述二义性强度还不够,那我们还可以写出可读性更加逆天的代码。

destruct.png

猫眼可见,undefined 有没有精神分裂我不知道,但我快精神分裂了。

代码二义性还可能与代码的执行环境有关,譬如说一猫一样的代码,在不同的运行时,可能有一龙一猪的结果。

strict-mode.png

猫眼可见,我写你猜,谁都不爱。

大家大约会理直气壮地反驳,我们必不可能写出这样不当人的代码,var 是不可能 var 的,这辈子都不可能 var

问题在于,墨菲定律告诉我们,只要可能有 BUG,就有可能有 BUG。说不定你的猪队友下一秒就给你来个神助攻,毕竟不是每个人都像你如此好学,既关注了我,还给我打 call。

语冰以前也不相信倒牛奶这么“离离原上谱”的事件,但是写做“impossible”,读做“I M possible”。

事实上,大多数教程一般不会刻意教你去写错误的代码,这其实恰恰剥夺了我们犯错的权利。不犯错我们就不会去探究为什么,而对知识点的掌握只停留在表面是什么,很多人知错就改,下次还敢就是因为缺少了试错的成就感和多巴胺,不知道 BUG 的 G 点在哪里,没有形成稳固的情绪记忆。

请相信我,永远写正确的代码本身就是一件不正确的事情,你会看到这期内容就是因为语冰被坑了气不过,才给祂载入日记。

语冰很喜欢的一部神作《七龙珠》里的赛亚人,每次从濒死体验中绝处逢生战斗力就会增量更新,这个设定其实蛮科学的,譬如说我们身边一些“量变到质变”的粒子,包括但不限于:

  • 骨折之后骨头更加坚硬了
  • 健身也是肌肉轻度撕裂后增生
  • 记忆也是不断复习巩固

语冰并不是让大家在物理层面去骨折,而是鼓励大家从 BUG 中学习。私以为大神从来不是没有 BUG,而是 fix 了足够多的 BUG。正如爱迪生所说,我没有失败 999 次,而是成功了 999 次,我成功证明了那些方法完全达咩。

综上所述,undefined 的二义性在于可能产生局部的副作用,一猫一样的代码在不同运行时也可以有一龙一猪的结果,最终导致一千个麻瓜眼中有一千个哈利波特,读码人集体精神分裂。


3. 未定义的 undefined 为何语义不明?

除了可维护性感人的复合 BUG 和可读性感人的代码二义性,undefined 自身的语义也很难把握。

举个粒子,因为太麻烦就全写 undefined 了。

init.png

猫眼可见,原则上允许我们可以无脑地使用 undefined 初始化任何变量,万物皆可 undefined

虽然但是,绝对的光明等于绝对的黑暗,绝对的权力导致绝对的腐败。undefined 的无能恰恰在于祂无所不能,语冰有幸百度了一本书叫《选择的悖论》,这大约也是 undefined 的悖论。

代码是写给人看的,代码的信息越具体明确越好,偏偏 undefined 既模糊又抽象。你知道的,我们接触的大多数资料会告诉我们 undefined 的意义是“未定义/无值”。

虽然但是,准确而无用的观念,终究还是无用的。undefined 的正确打开方式就是无为,使用 undefined 的最佳方式是不使用祂。

题外话

初入计算机行业的人或者大学计算机相关专业毕业生,很多因缺少实战经验,就业处处碰壁。下面我们来看两组数据:

  • 2023届全国高校毕业生预计达到1158万人,就业形势严峻;
  • 《新职业在线学习平台发展报告》 ,显示国内Python人才缺口高达40万,而人工智能人才目前缺口超过500万。

在这个大数据的时代,你要想走在潮流前端,就必须要学习前沿有用的知识。而今人工智能和数据分析爆发,python就是一颗冉冉升起的新星。

全球知名TIOBE编程语言社区发布了2023年最新的编程语言排行榜。我们一起来看看
在这里插入图片描述

口说无凭,请大家继续来看一下Python的招聘数据。

据职友集数据显示,分别来自50家招聘网站,与Python有关的招聘职位薪资待遇如下:

图片
图片

那么为什么各地对Python工程师需求这么大?工资给的这么高?因为Python程序员太少啦!很多高校并未开设Python课程,因此市场上Python开发人才供小于求。很多企业为了争夺有限的Python程序员,不得不给出极其丰厚的薪资待遇,现在初级Python开发工程师的起薪一般在10-20K!

目前来学的人群分为以下几类:

第一类:入行编程新手:大学刚毕业或者其他行业转岗,想从事编程开发的工作,目前认为Python比较火,想入行;Python简单易学,非常适合新手入门。

第二类:Linux系统运维人员:Linux运维以繁杂著称,对人员系统掌握知识的能力要求非常高,那么也就需要一个编程语言能解决自动化的问题,Python开发运维工作是首选,Python运维工资的薪资普遍比Linux运维人员的工资高。

第三类:做数据分析或者人工智能:不管是常见的大数据分析或者一般的金融分析、科学分析都比较大程度的应用了数据分析,人工智能的一些常见应用也使用了Python的一些技术。

第四类:在职程序员转Python开发:平常只关注div+css这些页面技术,很多时候其实需要与后端开发人员进行交互的,现在有很多Java程序在转到Python语言,他们都被Python代码的优美和开发效率所折服。

第五类:其他:一些工程师以前在做很多SEO优化的时候,苦于不会编程,一些程序上面的问题,得不到解决,只能做做简单的页面优化。现在学会Python之后,你和我一样都可以编写一些查询收录,排名,自动生成网络地图的程序,解决棘手的SEO问题。

当然,这里总结的只是常见的一些情况,关于职业和岗位。

Python的优点:

  • 易于学习:简单、易学、对新手极度友好。
  • 免费开源:Python的所有内容都是免费开源的,不需要花一分钱就可以免费使用Python,并且可以自由地发布这个软件的拷贝、阅读其源代码、对其做改动、把其一部分用于新的自由软件中;
  • 可扩展:Python除了使用Python本身编写外,还可以混合使用像C语言、Java语言等编写;

对于0基础小白入门:

如果你是零基础小白,想快速入门Python是可以考虑的。
一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以找到适合自己的学习方案

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、机器学习等习教程。带你从零基础系统性的学好Python!

👉Python学习路线汇总👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取哈)

在这里插入图片描述

👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述
温馨提示:篇幅有限,已打包文件夹,获取方式在:文末

👉实战案例👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

👉100道Python练习题👈

检查学习结果。
在这里插入图片描述

👉面试刷题👈

在这里插入图片描述

在这里插入图片描述

👉python副业兼职与全职路线👈

在这里插入图片描述

上述这份完整版的Python全套学习资料已经上传CSDN官方,朋友们如果需要可以微信扫描下方CSDN官方认证二维码 即可领取↓↓↓

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值