!!
将变量转换成布尔类型有时,我们需要检查一些变量是否存在,或者它是否具有有效值,从而将它们的值视为
true
。对于做这样的检查,你可以使用!!
(双重否定运算符),它能自动将任何类型的数据转换为布尔值,只有这些变量才会返回false:0,null,"",undefined或NaN
,其他的都返回true
。我们来看看这个简单的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function Account(cash) { this.cash = cash; this.hasMoney = !!cash; } var account = new Account(100.50); console.log(account.cash); // 100.50 console.log(account.hasMoney); // true var emptyAccount = new Account(0); console.log(emptyAccount.cash); // 0 console.log(emptyAccount.hasMoney); // false |
在这个例子中,如果account.cash
的值大于零,则account.hasMoney
的值就是true
。
2) 使用+
将变量转换成数字
这个转换超级简单,但它只适用于数字字符串,不然就会返回NaN
(不是数字)。看看这个例子:
1 2 3 4 5 6 7 8 9 |
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toNumber</span>(<span class="hljs-params">strNumber</span>) </span>{ <span class="hljs-keyword">return</span> +strNumber; } <span class="hljs-built_in">console</span>.log(toNumber(<span class="hljs-string">"1234"</span>)); <span class="hljs-comment">// </span> <span class="hljs-number">1234</span> <span class="hljs-built_in">console</span>.log(toNumber(<span class="hljs-string">"ACB"</span>)); <span class="hljs-comment">// </span> <span class="hljs-literal">NaN</span> |
这个转换操作也可以作用于Date
,在这种情况下,它将返回时间戳:
1 2 |
<span class="hljs-built_in">console</span>.log(+<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()) <span class="hljs-comment">// </span> <span class="hljs-number">1461288164385</span> |
3) 短路条件
如果你看到过这种类似的代码:
1 2 3 4 |
<span class="hljs-keyword">if</span> (conected) { login(); } |
那么你可以在这两个变量之间使用&&
(AND运算符)来缩短代码。例如,前面的代码可以缩减到一行:
1 2 |
conected && login(); |
你也可以用这种方法来检查对象中是否存在某些属性或函数。类似于以下代码:
1 2 |
user && user.login(); |
4) 使用||
设置默认值
在ES6中有默认参数这个功能。为了在旧版浏览器中模拟此功能,你可以使用||
(OR运算符),并把默认值作为它的第二个参数。如果第一个参数返回false
,那么第二个参数将会被作为默认值返回。看下这个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">User</span>(<span class="hljs-params">name, age</span>) </span>{ <span class="hljs-keyword">this</span>.name = name || <span class="hljs-string">"Oliver Queen"</span>; <span class="hljs-keyword">this</span>.age = age || <span class="hljs-number">27</span>; } <span class="hljs-keyword">var</span> user1 = <span class="hljs-keyword">new</span> User(); <span class="hljs-built_in">console</span>.log(user1.name); <span class="hljs-comment">// </span> Oliver Queen <span class="hljs-built_in">console</span>.log(user1.age); <span class="hljs-comment">// 27</span> <span class="hljs-keyword">var</span> user2 = <span class="hljs-keyword">new</span> User(<span class="hljs-string">"Barry Allen"</span>, <span class="hljs-number">25</span>); <span class="hljs-built_in">console</span>.log(user2.name); <span class="hljs-comment">// Barry </span> Allen <span class="hljs-built_in">console</span>.log(user2.age); <span class="hljs-comment">// 25 </span> |
5) 在循环中缓存array.length
这个技巧非常简单,并且在循环处理大数组时能够避免对性能造成巨大的影响。基本上几乎每个人都是这样使用for来循环遍历一个数组的:
1 2 3 4 5 |
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < array.length; i++) { <span class="hljs-built_in">console</span>.log(array); } |
如果你使用较小的数组,那还好,但是如果处理大数组,则此代码将在每个循环里重复计算数组的大小,这会产生一定的延迟。为了避免这种情况,你可以在变量中缓存array.length
,以便在循环中每次都使用缓存来代替array.length
:
1 2 3 4 5 6 |
<span class="hljs-keyword">var</span> length = array.length; <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < length; i++) { <span class="hljs-built_in">console</span>.log(array); } |
为了更简洁,可以这么写:
1 2 3 4 |
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>, length = array.length; i < length; i++) { <span class="hljs-built_in">console</span>.log(array); } |
6) 检测对象中的属性
当你需要检查某些属性是否存在,避免运行未定义的函数或属性时,这个技巧非常有用。如果你打算编写跨浏览器代码,你也可能会用到这个技术。例如,我们假设你需要编写与旧版Internet Explorer 6兼容的代码,并且想要使用document.querySelector()
来通过ID获取某些元素。 但是,在现代浏览器中,这个函数不存在。所以,要检查这个函数是否存在,你可以使用in
运算符。看下这个例子:
1 2 3 4 5 6 7 |
<span class="hljs-keyword">if</span> (<span class="hljs-string">'querySelector'</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">document</span>) { <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#id"</span>); } <span class="hljs-keyword">else</span> { <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"id"</span>); } |
在这种情况下,如果在document
中没有querySelector
函数,它就会使用document.getElementById()
作为代替。
7) 获取数组的最后一个元素
Array.prototype.slice(begin,end)
可以用来裁剪数组。但是如果没有设置结束参数end
的值的话,该函数会自动将end
设置为数组长度值。我认为很少有人知道这个函数可以接受负值,如果你将begin
设置一个负数的话,你就能从数组中获取到倒数的元素:
1 2 3 4 5 6 7 |
<span class="hljs-keyword">var</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>]; <span class="hljs-built_in">console</span>.log(array.slice(<span class="hljs-number">-1</span>)); <span class="hljs-comment">// </span> [<span class="hljs-number">6</span>] <span class="hljs-built_in">console</span>.log(array.slice(<span class="hljs-number">-2</span>)); <span class="hljs-comment">// </span> [<span class="hljs-number">5</span>,<span class="hljs-number">6</span>] <span class="hljs-built_in">console</span>.log(array.slice(<span class="hljs-number">-3</span>)); <span class="hljs-comment">// [4,5,6] </span> |
8) 数组截断
这个技术可以锁定数组的大小,这对于要删除数组中固定数量的元素是非常有用的。例如,如果你有一个包含10个元素的数组,但是你只想获得前五个元素,则可以通过设置array.length
来阶段数组。看下这个例子:
= 5
1 2 3 4 5 6 7 8 |
<span class="hljs-keyword">var</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>]; <span class="hljs-built_in">console</span>.log(array.length); <span class="hljs-comment">// 6 </span> array.length = <span class="hljs-number">3</span>; <span class="hljs-built_in">console</span>.log(array.length); <span class="hljs-comment">// 3 </span> <span class="hljs-built_in">console</span>.log(array); <span class="hljs-comment">// </span> [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>] |
9) 全部替换
String.replace()
函数允许使用String
和Regex
来替换字符串,这个函数本身只能替换第一个匹配的串。但是你可以在正则表达式末尾添加/g
来模拟replaceAll()
函数:
1 2 3 4 5 |
var string = "john john"; console.log(string.replace(/hn/, "ana")); // "joana john" console.log(string.replace(/hn/g, "ana")); // "joana joana" |
10) 合并数组
如果你需要合并两个数组,你可以使用Array.concat()
函数:
1 2 3 4 5 |
<span class="hljs-keyword">var</span> array1 = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]; <span class="hljs-keyword">var</span> array2 = [<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>]; <span class="hljs-built_in">console</span>.log(array1.concat(array2)); <span class="hljs-comment">// </span> [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>]; |
但是,这个函数对于大数组来说不并合适,因为它将会创建一个新的数组并消耗大量的内存。在这种情况下,你可以使用Array.push.apply(arr1,arr2)
,它不会创建一个新数组,而是将第二个数组合并到第一个数组中,以减少内存使用:
1 2 3 4 5 6 |
<span class="hljs-keyword">var</span> array1 = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]; <span class="hljs-keyword">var</span> array2 = [<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>]; <span class="hljs-built_in">console</span>.log(array1.push.apply(array1, array2)); <span class="hljs-comment">// </span> [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>]; |
11) 把NodeList
转换成数组
如果运行document.querySelectorAll("p")
函数,它会返回一个DOM
元素数组,即NodeList
对象。但是这个对象并没有一些属于数组的函数,例如:sort(),reduce(),map(),filter()
。为了启用这些函数,以及数组的其他的原生函数,你需要将NodeList转换为数组。要进行转换,只需使用这个函数:[]
:
.slice.call(elements)
1 2 3 4 5 |
<span class="hljs-keyword">var</span> elements = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">"p"</span>); <span class="hljs-comment">// </span> NodeList <span class="hljs-keyword">var</span> arrayElements = [].slice.call(elements); <span class="hljs-comment">// 现在已经转换成数组了</span> <span class="hljs-keyword">var</span> arrayElements = <span class="hljs-built_in">Array</span>.from(elements); <span class="hljs-comment">// 把NodeList转换成数组的另外一个方法</span> |
12) 对数组元素进行洗牌
如果要像外部库Lodash
那样对数据元素重新洗牌,只需使用这个技巧:
1 2 3 4 5 6 |
<span class="hljs-keyword">var</span> list = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]; <span class="hljs-built_in">console</span>.log(list.sort(<span class="hljs-function"><span class="hljs-keyword">function</span>() </span>{ <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.random() - <span class="hljs-number">0.5</span> })); <span class="hljs-comment">// [2,1,3]</span> |