New issue

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

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

Already on GitHub? Sign in to your account

常见javascript hack解释 #6

Open
8788 opened this Issue Nov 25, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@8788
Copy link
Owner

8788 commented Nov 25, 2018

历史文章,发布于2014年,现迁移到issues

一些javascript技巧被资深的程序员广泛使用。然而对于初学者来说,有的技巧的含义并不是那么的显而易见。这些技巧往往使用的并不是语言的直接含义,而是利用一些特性或者副作用来达到目的。下面我会对一些常用的技巧做出解释。

你应该明白,这些技巧中的很多都属于hack,不应该在日常开发中使用。这篇文章的目的是解释这些hack是如何工作的,并不是推荐去使用它们。

使用!!将值转换为布尔型

在javascript中,所有的东西都能被转换成“真”或“假”。也就是说,当你把一个对象放进if语句的条件中,执行时,要么走条件为真的分支,要么就走条件为假的分支。

0, false, "", null, undefined, NaN为假,其他对象都为真。有时候想将一个对象转换成布尔值,你可以使用!!

另外,如果不是if (x == "test")这种形式,你可以简单的写成if (x),当x为false时,程序将直接运行其它块。

使用+str将字符串转换成数字

在javascript中,当+作为一元运算符使用时会返回一个数值或NaN。有时当你想知道一个变量是否是数值(number)时,你可以这样来写代码x === +x(见underscorejs源码)。

这种方法意图并不明显,通常,你应该使用parseFloat或者parseInt(x, 10)来将一个变量转换成数值型(number)。

使用||来提供默认值

在javascript中,||是一个短路求值的例子,也常用在其他语言当中。||操作符会首页判断左边表达式的值,如果为false,则继续判断右边。在任何情况下它都会返回第一个值不为false的结果,参考下面例子:

function setAge(age) {
  this.age = age || 10;
}

setAge();

我们没有传入age的值,因此age || 10会返回10,这是给变量设置默认值的非常好的一个方式。事实上这段代码等价于:

var x;
if (age) {
    this.age = age;
} else {
    this.age = 10;
}

很明显,前者代码更简洁,这就是为什么到处都在使用它的原因。

就我自己而言,我经常使用这种方式,因为足够的简洁明了。需要注意的是,这种方式你没法设置age0,因为0false,因此下面的方法应该是一个更好的方案(但是代码稍微有些冗长):

this.age = (typeof age !== "undefined") ? age : 10;

使用void 0来替代undefined

关键字void后跟着一个参数,并总会返回undefined。为什么不直接使用undefined?因为在一些浏览器中,undefined仅仅被视作一个变量,并且可以被重新赋值,而前者可以给我们更高的信赖。虽然你可以看到这种写法在很多代码或库中被使用,但是我并不建议经常使用它,因为所有遵循EC5的浏览器已经禁止重写undefined了。

封装模式(function() {...})()

当你想要封装代码时,你可以用一个匿名函数包裹代码,然后立刻执行这个匿名函数。在javascript中,有两种作用域:全局作用域和局部(函数)作用域。你写的代码包括变量和函数声明,不论在任何位置,都会进入全局作用域。通常,你可以将代码封装在匿名函数的内部,而只向全局作用域暴露调用接口的方法名。这个模式使用起来也非常方便,请看以下代码:

(function() {
  function div(a, b) {
    return a / b;
  }

  function divBy5(x) {
    return div(x, 5);
  }

  window.divBy5 = divBy5;
})()

div // => undefined
divBy5(10); // => 2

本文中列出的这些hack中,这条确实是无害的,你应该在代码中使用它以防止代码的内部逻辑暴露在全局作用域中。

总之,我想提醒的是,你写的任何代码都应该本着让其他人读起来简单易懂为原则。

一些文章中列出的问题,在ES6标准中已经通过优雅的方式进行了解决。例如,在未来你不需要使用age = age || 10这种模式了,ES6提供的一种更好的方式来设置默认值:

function(age = 10) {
    ...
}

另一个例子是(function() {...})()这种模式,当现代浏览器支持ES6 modules之后,你可以使用模块化来代替。

译自:JavaScript hacks explained

@8788 8788 added the 2014 label Nov 25, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment