Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

为什么用「void 0」代替「undefined」 #1

Open
lessfish opened this issue May 16, 2016 · 59 comments
Open

为什么用「void 0」代替「undefined」 #1

lessfish opened this issue May 16, 2016 · 59 comments

Comments

@lessfish
Copy link
Owner

lessfish commented May 16, 2016

Why underscore

最近开始看 underscore源码,并将 underscore源码解读 放在了我的 2016计划 中。

阅读一些著名框架类库的源码,就好像和一个个大师对话,你会学到很多。为什么是 underscore?最主要的原因是 underscore 简短精悍(约 1.5k 行),封装了 100 多个有用的方法,耦合度低,非常适合逐个方法阅读,适合楼主这样的 JavaScript 初学者。从中,你不仅可以学到用 void 0 代替 undefined 避免 undefined 被重写等一些小技巧 ,也可以学到变量类型判断、函数节流&函数去抖等常用的方法,还可以学到很多浏览器兼容的 hack,更可以学到作者的整体设计思路以及 API 设计的原理(向后兼容)。

之后楼主会写一系列的文章跟大家分享在源码阅读中学习到的知识。

欢迎围观~ (如果有兴趣,欢迎 star & watch~)您的关注是楼主继续写作的动力

Why does void 0 replace undefined

说来惭愧,underscore 源码解读这个 Repo 放在 Github 都已经 20 天没有更新了,要不是今天 "不小心" 注意到,我居然都快忘了(是不是 lu 多了),所以今晚无论如何都要 lu 出第一篇(毕竟万事开头难)。相对于其他源码解读的文章,基本都会从整体设计开始讲起,楼主觉得 underscore 这个库有点特殊,so 决定按照自己的思路,从用 void 0 代替 undefined 说起。

underscore 源码没有出现 undefined(注意,其实有出现一处,是为 "undefined",而不是 undefined),而用 void 0 代替之。为什么要这么做?我们可以从两部分解读,其一是 undefined 哪里不好了,你非得找个替代品?其二就是替代品为毛要找 void 0?

我们先看第一点,答案很简单,undefined 并不是保留词(reserved word),它只是全局对象的一个属性,在低版本 IE 中能被重写。

var undefined = 10;

// undefined -- chrome
// 10 -- IE 8
alert(undefined);

事实上,undefined 在 ES5 中已经是全局对象的一个只读(read-only)属性了,它不能被重写。但是在局部作用域中,还是可以被重写的。

(function() {
  var undefined = 10;

  // 10 -- chrome
  alert(undefined);
})();

(function() {
  undefined = 10;

  // undefined -- chrome
  alert(undefined);
})();

接下来思考第二个问题,为毛找的替代品是 void 0?

我们来看看 MDN 的解释:

The void operator evaluates the given expression and then returns undefined.

意思是说 void 运算符能对给定的表达式进行求值,然后返回 undefined。也就是说,void 后面你随便跟上一个表达式,返回的都是 undefined,都能完美代替 undefined!那么,这其中最短的是什么呢?毫无疑问就是 void 0 了。其实用 void 1,void (1+1),void (0) 或者 void "hello",void (new Date()) 等等,都是一样的效果。更重要的前提是,void 是不能被重写的(cannot be overidden)。

那么,ES5 大环境下,void 0 就没有用武之地了吗?答案是否定的,用 void 0 代替 undefined 能节省不少字节的大小,事实上,不少 JavaScript 压缩工具在压缩过程中,正是将 undefined 用 void 0 代替掉了。

一篇不长的文章写了两个小时,心累,不点个赞、不关注下楼主的 Repo 你觉得好意思吗?https://github.com/hanzichi/underscore-analysis

Read More

@lessfish lessfish added the bug label May 21, 2016
@itsmatthu
Copy link

不小心走进了楼主的博客,我很欣赏楼主对于库的解读和学习。我自己也在学习和使用过程中。这篇文章显得有些虎头蛇尾了,较大的篇幅解读了undefined是可以被重写,但是对于为什么能减少字节,压缩工具的实现,居然一句话带过了,这样显得结尾有些草率和仓促了,继续努力

@lessfish
Copy link
Owner Author

谢谢。
可能我们的重点不同吧,至于压缩工具的实现,这似乎有点 "偏题" 了,反正我是这么认为的~

@lessfish lessfish reopened this May 23, 2016
@idda
Copy link

idda commented Jun 22, 2016

蛮好,加油

@juemin90
Copy link

已关注,加油po主

@lessfish
Copy link
Owner Author

@juemin90 多谢支持!

@jiapeiyang
Copy link

长见识了,谢谢楼主

@lessfish
Copy link
Owner Author

@jiapeiyang 感谢支持~

@Wangbaogang
Copy link

支持支持!最近在读underscore源码,楼主的注释版读起来很棒!

@lessfish
Copy link
Owner Author

lessfish commented Sep 6, 2016

@Wangbaogang thanks a lot!

@lcoder
Copy link

lcoder commented Sep 11, 2016

lz棒棒哒

@git-lt
Copy link

git-lt commented Sep 19, 2016

写的不错

@zhw2590582
Copy link

这个系列,我看定了

@Melody12ab
Copy link

已start,楼主加油!!!

1 similar comment
@snayan
Copy link

snayan commented Oct 14, 2016

已start,楼主加油!!!

@lessfish lessfish changed the title 为什么用 void 0 代替 undefined 为什么用「void 0」代替「undefined」 Oct 18, 2016
@cleartime
Copy link

已start,楼主加油!!!

@waitinghope
Copy link

你不知道的js中卷,2.4.2也谈到了void 0
同时举的例子我觉得不太好。

@lessfish
Copy link
Owner Author

@waitinghope 谢谢指出。没看过「你不知道的js」,不介意的话举个更好的例子?我可以补充或者修改下

@waitinghope
Copy link

@hanzichi 给你的outlook发了封信.

@lessfish
Copy link
Owner Author

lessfish commented Nov 10, 2016

@waitinghope 看完了,其实他的意思就是「void + 任何数字」返回的都是 undefined。如果在一个函数中又要执行一个定时器,又要 return,写成 return void setTimeout(...) 的形式,不失为一种 hack

https://book.douban.com/review/8163708/ 他说的不对吧,如果 App.ready 了,那么就会返回 result 值了,如果 !App.ready ,那么返回的是 undefined

@waitinghope
Copy link

我觉得他的意思是:var t; 然后return t;
这个时候if(t)是判断不出来啥的.

@lessfish
Copy link
Owner Author

@waitinghope 理解有出入吧 ...

@xyyie
Copy link

xyyie commented Nov 11, 2016

来看看分析的,还是赞下。

@LastKing
Copy link

LastKing commented Dec 2, 2016

0.0 重点是写出来了,但是 感觉好头重尾轻。。。不过还是 理解。。!!点个赞赞!

@MontageD
Copy link

看出分析很用心,值得学习。

@Sy-52
Copy link

Sy-52 commented Jan 16, 2017

@hanzichi ok,捋顺了,感谢你愿意花时间解惑 ^_^

@w-y
Copy link

w-y commented Jan 23, 2017

0.._比void 0更短

@lessfish
Copy link
Owner Author

@w-y 还真是,测了下 IE8 也没有问题,请教下这是什么原理?

@w-y
Copy link

w-y commented Jan 23, 2017

@hanzichi 类似 这种 0['x'] 但0.x会语法错误 4个字符的话应该还有几种写法

@lessfish
Copy link
Owner Author

@w-y 感谢,学习了~

@lcoder
Copy link

lcoder commented Jan 24, 2017

@w-y 为什么我chrome测试:console.log( 0.. ) 报错?

@lessfish
Copy link
Owner Author

@lcoder 后面还跟了个 _ ,意思就是 0['_']

@195286381
Copy link

楼主分析的不错 学到新知识

@pageliu16
Copy link

谢谢楼主,正在研究中

@wave1992
Copy link

~👍

@district10
Copy link

我记得 lodash 里面是用 var undefined 来定义 undefined... 也是奇妙. 自己定义 undefined, 然后不 define 它... 于是就是 undefined.

@WalkerKing
Copy link

非常感谢分享,正在看您的注释版的源码

@fxk01
Copy link

fxk01 commented Feb 2, 2018

写的很好

@shangguanhonglei
Copy link

undefined不是js的保留关键字,所以undefined可以作为变量被赋值,至于为什么使用void 0 ,楼主的解析还是不错的

@sighWang
Copy link

sighWang commented Feb 12, 2018

建议楼主简练下语言,删掉「说来惭愧...」等。这样子读起文章来会更专注

@pq1949
Copy link

pq1949 commented May 9, 2018

为什么不用 null 代替 void 0

@delayk
Copy link

delayk commented May 9, 2018

@pq1949 null与undefined等价吗?

@eventhorizon-cli
Copy link

@delayk
null == undefined
null !== undefined

@delayk
Copy link

delayk commented May 9, 2018

@blurhkh ==是做了隐式转换的, null === undefined的结果可是false哦
你可以看下underscore源码里用来判断undefined的地方都是用===而不是==

@eventhorizon-cli
Copy link

@delayk 嗯,我只是说null !== undefined

@delayk
Copy link

delayk commented May 9, 2018

@blurhkh 好吧…那你应该回复 @pq1949 而不是回复我

@attraction11
Copy link

看了楼主与大家的讨论很有收获,自己实际测试一下确实如此。在全局作用域中以widow的属性优先,局部作用域中可以实现定义变量。但并不如void 0 字符少 。

@pluscai
Copy link

pluscai commented Apr 11, 2019

今天在看框架时刚好遇到这个,有收货,多谢!

@wshuhd
Copy link

wshuhd commented Nov 8, 2019

好了好了,star了

@HomyeeKing
Copy link

let a = 1
void a+1//NaN

@MBRjun
Copy link

MBRjun commented Apr 23, 2023

刚才去试了下在线 JS 压缩工具(基于 UglifyJS 3),发现

  • true > !0
  • false > !1
  • null > null
  • undefined > void 0

@xr-betty
Copy link

xr-betty commented Apr 23, 2023 via email

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests