JavaScript void 运算符

目录

  1. void 是什么?
  2. void 的做用
  3. void 优先级
  4. void 的执行
  5. 为何要用 void ?

前言

前两天在开发项目的公共基础库时,无心间在看 moment.js 源代码的时候发现这样一个 util 函数。这个函数做用无非就是判断输入否是 undefined ,这个不是关键,关键是 void 这个引发了个人注意,这里为何不直接使用 input === undefined ?而是使用这种形式来判断了。带着疑问咱们今天就一块儿来看看 JavaScript void 运算符。javascript

export default function isUndefined(input) {
    return input === void 0;
}
复制代码

1. void 是什么?

void 运算符 对给定的表达式进行求值,而后返回 undefined。语法就是 void expression 。void 是一个一元运算符,它能够出如今任意类型的操做数以前执行操做数,却忽略操做数的返回值,返回一个 undefined。void 在表达式的左边,void 右边的表达式能够是带括号形式(例如:void(0)),也能够是不带括号的形式(例如:void 0)。java

2. void 的做用

1. JavaScript URIs

若是有印象的同窗是否是会发现,咱们在阻止 a 标签的默认事件是会用到这个。web

<a href="javascript:void(0);">
<a href="javascript:void(0);"> 这个连接点击以后不会作任何事情,若是去掉 void(), 点击以后整个页面会被替换成一个字符 0。 </a>
<p> chrome中即便<a href="javascript:0;">也没变化,firefox中会变成一个字符串0 </p> <a href="javascript:void(document.body.style.backgroundColor='green');"> 点击这个连接会让页面背景变成绿色。 </a> 复制代码

注意,虽然这么作是可行的,但利用 javascript: 伪协议来执行 JavaScript 代码是不推荐的,推荐的作法是为连接元素绑定事件。chrome

2. 当即调用的函数表达式

在使用当即执行的函数表达式时,能够利用 void 运算符让 JavaScript 引擎把一个function关键字识别成函数表达式而不是函数声明(语句)。express

void function iife() {
    var bar = function () {};
    var baz = function () {};
    var foo = function () {
        bar();
        baz();
     };
    var biz = function () {};
    foo();
    biz();
}();
复制代码

3. 在箭头函数中避免泄漏

箭头函数标准中,容许在函数体不使用括号来直接返回值。 若是右侧调用了一个本来没有返回值的函数,其返回值改变后,则会致使非预期的反作用。 安全起见,当函数返回值是一个不会被使用到的时候,应该使用 void 运算符,来确保返回 undefined(以下方示例),这样,当 API 改变时,并不会影响箭头函数的行为。segmentfault

button.onclick = () => void doSomething();
复制代码

确保了当 doSomething 的返回值从 undefined 变为 true 的时候,不会改变函数的行为。安全

3. void 优先级

因为 void 运算符的优先级比较高(14),高于普通运算符的优先级,因此在使用时应该使用小括号明确 void 运算符操做的操做数,避免引起错误。 在下面的示例代码中,因为第一行没有使用小括号,void 运算符优先计算,恒等于( void 2)- 1,也就是 undefined - 1,结果为 NaN,在第二行代码中用括号包含了 (2-1),因此优先因而先计算2-1,在处理 void,恒等于 void (1),结果也就是 undefined。markdown

console.log(void 2 - 1);  //返回NaN
console.log(void (2 - 1));  //返回undefined
复制代码

4. void 的执行

image.png 在 262 ECMA 中,对 void 有一个执行步骤的解释,大体的解读一下:框架

  1. 执行 UnaryExpression 并把返回值赋值给 expr
  2. 调用 GetValue(expr)
  3. 返回 undefined

注意最后的一句话,GetValue必定要调用,即便它的值不会被用到,可是这个表达式可能有反作用。其实这个反作用是什么,并无解释。既然void xx === undefined,咱们回到最开始的问题,哪 void 0 、void 100、void xx()、void 无论什么操做,返回的都是 undefined 。哪为何在 moment.js 中不直接写 input === undefined。函数

5. 为何要用 void ?

咱们知道 undefined 在 JavaScript 中是一个保留字。哪既然他是一个保留字,咱们就能够为它赋值。

function test() {
    var undefined = "不爱吃猫的鱼er";
    console.log(undefined); // 不爱吃猫的鱼er
}
test();
console.log(undefined); // undefined
复制代码

image.png 赋值以后你提取到的 undefined 就不等于 undefined了,固然若是咱们使用的是 window 对象上的 undefined,也可能被赋值 。因此你直接使用的 undefined ,不必定是100%可靠。因而在不少框架或者基础 JS 库中,采用void方式获取 undefined 便成了通用准则。例如 moment.js、Backbone.js、underscore.js,在他们的源码中对 undefined 的使用都是使用 void 0 代替。 • moment.js

export default function isUndefined(input) {
    return input === void 0;
}
复制代码

• Backbone.js

if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
复制代码

• underscore.js

_.isUndefined = function(obj) {
    return obj === void 0;
}
复制代码

除了采用void能保证取到 undefined 值之外,AngularJS 的源码里经过函数调用不传参数,确保了 undefined 参数的值是一个 undefined。

(function(window, document, undefined) {
    //.....
})(window, document);
复制代码

总结

经过 void xx 这种方式来获取 undefined,比直接使用 undefined 来的更加可靠安全,因此在不少的库、框架中都使用 void xx 这种方式来处理undefined ,保证使用到的是安全可靠的 undefined。这种方式咱们在平常的项目开发或者的封装也能够借鉴起来。

结束语

若是文章中什么不对或者写的很差的地方,请你们多多指正,谢谢!码字不易,点个赞加个关注吧!

参考

developer.mozilla.org/zh-CN/docs/…262.ecma-international.org/5.1/#sec-11…segmentfault.com/a/119000000…blog.csdn.net/mm19931027/…

相关文章
相关标签/搜索