Open 8788 opened 5 years ago
历史文章,发布于2014年,现迁移到issues
一些javascript技巧被资深的程序员广泛使用。然而对于初学者来说,有的技巧的含义并不是那么的显而易见。这些技巧往往使用的并不是语言的直接含义,而是利用一些特性或者副作用来达到目的。下面我会对一些常用的技巧做出解释。
你应该明白,这些技巧中的很多都属于hack,不应该在日常开发中使用。这篇文章的目的是解释这些hack是如何工作的,并不是推荐去使用它们。
!!
在javascript中,所有的东西都能被转换成“真”或“假”。也就是说,当你把一个对象放进if语句的条件中,执行时,要么走条件为真的分支,要么就走条件为假的分支。
if
0, false, "", null, undefined, NaN为假,其他对象都为真。有时候想将一个对象转换成布尔值,你可以使用!!。
0
false
""
null
undefined
NaN
另外,如果不是if (x == "test")这种形式,你可以简单的写成if (x),当x为false时,程序将直接运行其它块。
if (x == "test")
if (x)
x
+str
在javascript中,当+作为一元运算符使用时会返回一个数值或NaN。有时当你想知道一个变量是否是数值(number)时,你可以这样来写代码x === +x(见underscorejs源码)。
+
number
x === +x
underscorejs
这种方法意图并不明显,通常,你应该使用parseFloat或者parseInt(x, 10)来将一个变量转换成数值型(number)。
parseFloat
parseInt(x, 10)
||
在javascript中,||是一个短路求值的例子,也常用在其他语言当中。||操作符会首页判断左边表达式的值,如果为false,则继续判断右边。在任何情况下它都会返回第一个值不为false的结果,参考下面例子:
function setAge(age) { this.age = age || 10; } setAge();
我们没有传入age的值,因此age || 10会返回10,这是给变量设置默认值的非常好的一个方式。事实上这段代码等价于:
age || 10
10
var x; if (age) { this.age = age; } else { this.age = 10; }
很明显,前者代码更简洁,这就是为什么到处都在使用它的原因。
就我自己而言,我经常使用这种方式,因为足够的简洁明了。需要注意的是,这种方式你没法设置age为0,因为0是false,因此下面的方法应该是一个更好的方案(但是代码稍微有些冗长):
age
this.age = (typeof age !== "undefined") ? age : 10;
void 0
关键字void后跟着一个参数,并总会返回undefined。为什么不直接使用undefined?因为在一些浏览器中,undefined仅仅被视作一个变量,并且可以被重新赋值,而前者可以给我们更高的信赖。虽然你可以看到这种写法在很多代码或库中被使用,但是我并不建议经常使用它,因为所有遵循EC5的浏览器已经禁止重写undefined了。
void
EC5
(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提供的一种更好的方式来设置默认值:
ES6
age = age || 10
function(age = 10) { ... }
另一个例子是(function() {...})()这种模式,当现代浏览器支持ES6 modules之后,你可以使用模块化来代替。
译自:JavaScript hacks explained
一些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
的结果,参考下面例子:我们没有传入age的值,因此
age || 10
会返回10
,这是给变量设置默认值的非常好的一个方式。事实上这段代码等价于:很明显,前者代码更简洁,这就是为什么到处都在使用它的原因。
就我自己而言,我经常使用这种方式,因为足够的简洁明了。需要注意的是,这种方式你没法设置
age
为0
,因为0
是false
,因此下面的方法应该是一个更好的方案(但是代码稍微有些冗长):使用
void 0
来替代undefined
关键字
void
后跟着一个参数,并总会返回undefined
。为什么不直接使用undefined
?因为在一些浏览器中,undefined
仅仅被视作一个变量,并且可以被重新赋值,而前者可以给我们更高的信赖。虽然你可以看到这种写法在很多代码或库中被使用,但是我并不建议经常使用它,因为所有遵循EC5
的浏览器已经禁止重写undefined
了。封装模式
(function() {...})()
当你想要封装代码时,你可以用一个匿名函数包裹代码,然后立刻执行这个匿名函数。在javascript中,有两种作用域:全局作用域和局部(函数)作用域。你写的代码包括变量和函数声明,不论在任何位置,都会进入全局作用域。通常,你可以将代码封装在匿名函数的内部,而只向全局作用域暴露调用接口的方法名。这个模式使用起来也非常方便,请看以下代码:
本文中列出的这些hack中,这条确实是无害的,你应该在代码中使用它以防止代码的内部逻辑暴露在全局作用域中。
总之,我想提醒的是,你写的任何代码都应该本着让其他人读起来简单易懂为原则。
一些文章中列出的问题,在
ES6
标准中已经通过优雅的方式进行了解决。例如,在未来你不需要使用age = age || 10
这种模式了,ES6
提供的一种更好的方式来设置默认值:另一个例子是
(function() {...})()
这种模式,当现代浏览器支持ES6 modules之后,你可以使用模块化来代替。