当我开始学习JavaScript时,我列出了我在别人的代码、code challenge网站以及我使用的教程之外的任何地方发现的每一个节省时间的技巧。
从那时起,我就一直在为这个列表做贡献,在本文中,我将分享12个我认为特别聪明或有用的精选技巧。
虽然这些技巧中有许多在任何情况下都很方便,但其中一两个可能更适合Code Golf (Code golf 是一种娱乐性的计算机编程比赛,参赛者努力获得实现某种算法的尽可能短的源代码),而不是生产级代码,在生产级代码中,清晰往往比简洁更重要;我让你们自己来评判吧!
所以,没有特定的顺序,这里有12种简洁的方法来编写更简洁、更高效的代码
1.筛选不重复的元素
ARRAY
在ES6中已经介绍过 Set
对象类型,同时利用扩展运算符 ...
,我们可以用他们创建一个新的只有唯一值得数组。
const array = [1, 1, 2, 3, 5, 5, 1]
const uniqueArray = [...new Set(array)];
console.log(uniqueArray); // Result: [1, 2, 3, 5]
在ES6之前,隔离惟一值将涉及比这多得多的代码!
2.在循环体中缓存数组长度
LOOPS
当我们学习 for
循环时,我们被鼓励遵循这个标准结构:
for (let i = 0; i < array.length; i++){
console.log(i);
}
但是,使用这种语法, for
循环会在每次迭代时重新计算数组的长度。
有时这可能很有用,但在大多数情况下,缓存数组的长度以便只需要计算一次,这样做更好,性能也更好。我们可以这样做,在设置变量 i
的地方定义一个 length
变量, 像这样:
for (let i = 0, length = array.length; i < length; i++){
console.log(i);
}
这段代码和上面的代码一样简洁,但是这意味着随着数组长度的增加,并不会有运行时的损耗用来重新计算 Array.length
3.短路求值
CONDITIONALS
三元运算符是一种快速编写简单(有时不那么简单)条件语句的方法,如下所示:
x > 100 ? 'Above 100' : 'Below 100';
x > 100 ? (x > 200 ? 'Above 200' : 'Between 100-200') : 'Below 100';
但有时甚至三元运算符也比必要的复杂。相反,我们可以使用“与” &&
和 “或” ||
逻辑运算符以更简洁的方式计算某些表达式。这通常被称为“短路”或“短路求值”。
他是如何工作的
假设我们只想返回两个或多个选项中的一个。
使用 &&
会返回第一个 false
或“假值”,如果每一个操作数的值都为 true
,那么最后一个表达式的值将会被返回。
let one = 1, two = 2, three = 3;
console.log(one && two && three); // Result: 3
console.log(0 && null); // Result: 0
使用 ||
会返回第一个 true
或“真值”,如果每一个操作数的值都为 false
,那么最后一个表达式的值将会被返回。
let one = 1, two = 2, three = 3;
console.log(one || two || three); // Result: 1
console.log(0 || null); // Result: null
Example 1
假设我们需要返回一个变量的 length
,但是我们不知道这个变量的类型。
我们可以使用 if/else
语句来判断 foo
是否是可接受的类型,但是这样的语句太冗长了。短路求值允许我们这样做:
// With ||
return (foo || []).length;
// With &&
return ([] && foo).length;
在两种情况下,如果变量 foo
拥有 length
属性,那么 length
会被返回。否则空数组的 length
会被返回:0 。
Example 2
你在访问嵌套对象属性时遇到过问题吗?您可能不知道对象或子属性是否存在,这可能会导致令人沮丧的错误。
假设我们希望从 this.state
中获取一个叫 data
的属性,但是在程序成功的返回一个请求前, data
是未定义的。
调用 this.state.data
可能会阻止程序继续运行,这取决于我们在什么时候使用它。为了解决这个问题,我们可以用一个条件语句来包裹:
if (this.state.data) {
return this.state.data;
} else {
return 'Fetching Data';
}
但这看起来很重复,“或”运算符提供了一个更简洁的解决方案:
return (this.state.data || 'Fetching Data');
与例1不同,我们无法用 &&
对上面的代码进行重构。无论 this.state.data
是否是 undefined
, 'Fetching Data'&&this.state.data
都会返回 this.state.data
。这是因为 'Fetching Data'
是“真值”,所以当它被列在第一个时 &&
总是会忽略它。
一个新特性:可选链(Optional Chaining)
目前有一个提案,当试图返回树状结构深处的属性时,允许使用“可选链”(optional chaining)。在这个提案下,问号 ?
仅当属性不为 null
时,才可用于提取该属性。
例如,我们可以将上面的示例重构为 this.state.data?.()
,因此,仅当不为 null
时才返回 data
。
或者,如果我们主要关心是否定义了 state
,我们可以返回 this.state?.data
。
作为一项试验性质,该提案目前正处于第一阶段。您可以在这里阅读有关它的内容,现在可以通过Babel在JavaScript中使用它,方法是将@babel/plugin-proposal-option - link添加到 .babelrc
文件中。
4.转换为布尔对象
TYPE CONVERSION
除了常规的布尔值 true
和 false
之外,JavaScript还将所有其他值视为“真值”或“假值”。
除非另有定义,JavaScript中的所有值都是“真值”,除了 0
、""
、null
、undefined
、NaN
,当然还有false
,它们都是“假值”。
利用非运算符!
,我们可以很容易地在真和假之间切换,它也会将类型转换为“布尔类型”。
const true = !0;
const false = !1;
const alsoFalse = !!0;
console.log(true); // Result: true
console.log(typeof true); // Result: "boolean"
这种类型的转换在条件语句中非常方便,尽管你选择将 false
定义为 !1
的唯一原因可能是你正在 Code Golf!
5.转换为字符串对象
TYPE CONVERSION
要快速将数值转换为字符串,我们可以使用连接运算符 +
后跟一组空引号 ""
。
const val = 1 + "";
console.log(val); // Result: "1"
console.log(typeof val); // Result: "string"
6.转换为数值对象
TYPE CONVERSION
使用加法运算符 +
可以快速实现相反的效果。
let int = "15";
int = +int;
console.log(int); // Result: 15
console.log(typeof int); //Result: "number"
这也可用于将布尔值转换为数字,如下所示:
console.log(+true); // Return: 1
console.log(+false); // Return: 0
在某些上下文中, +
被解释为连接操作符,而不是加法操作符。当这种情况发生时(你希望返回一个整数,而不是浮点数),你可以使用两个波浪号: ~~
。
一个波浪号被称为“按位非”运算符,它等价于 -n-1
。例如, ~15
等于 -16
。
因为- (- n - 1) - 1 = n + 1 - 1 = n
,所以在一行中使用两个波浪号可以有效地抵消操作。换句话说,~ - 16
等于 15
。
const int = ~~"15"
console.log(int); // Result: 15
console.log(typeof int); //Result: "number"
尽管我想不出很多有用的例子,但是按位非操作也可以用来对布尔值进行操作:~true = -2
、 ~false = -1
。
7.快速乘方
OPERATIONS
从ES7开始,就可以使用幂运算符 **
作为幂函数的简写,这比写 Math.power(2,3)
要简单。这是一个简单的东西,但是依然出现在列表中,因为没有多少教程更新过这个操作符!
console.log(2 ** 3); // Result: 8
这不会与 ^
符号混淆, ^
符号通常用于表示指数,但在JavaScript中是按位或操作符。
在ES7之前,仅存在以2为基数的幂的简写,使用左移位操作符<<
:
// The following expressions are equivalent:
Math.pow(2, n);
2 << (n - 1);
2**n;
例如,2 << 3 = 16
等于2 ** 4 = 16
。
8.快速舍入
OPERATIONS
如果希望将浮点数转换为整数,可以使用 Math.floor()
、 Math.ceil()
或 Math.round()
。但还有一种更快的方法使用 |
,按位或运算符。
console.log(23.9 | 0); // Result: 23
console.log(-23.9 | 0); // Result: -23
|
的行为取决于处理的是正数还是负数,所以最好只在确定的情况下使用这个快捷方式。
如果 n
是正数, n | 0
向下取整。如果 n
是负数,则向上取整。它能有效地除去小数点后的数。你可以使用 ~~
获得如上所述的相同舍入效果。
删除最后一个数字
按位或运算符还可以用于从整数的末尾删除任意数量的数字。这意味着我们不需要使用这样的代码来转换类型:
let str = "1553";
Number(str.substring(0, str.length - 1));
相反,位或运算符允许我们这样写:
console.log(1553 / 10 | 0) // Result: 155
console.log(1553 / 100 | 0) // Result: 15
console.log(1553 / 1000 | 0) // Result: 1
9.Classes 内部自动绑定
CLASSES
我们可以在类方法中使用ES6箭头表示法,这样就隐含了绑定。这通常会在类构造函数中节省几行代码,我们可以愉快地告别这样的重复表达式:myMethod = this.myMethod.bind(this)
!
import React, { Component } from React;
export default class App extends Compononent {
constructor(props) {
super(props);
this.state = {};
}
myMethod = () => {
// This method is bound implicitly!
}
render() {
return (
<>
<div>
{this.myMethod()}
</div>
</>
)
}
};
10.截取数组
ARRAYS
如果您想从数组的末尾破坏性地删除值,则不需要使用 slice()
或 splice()
。
只需重新定义数组的长度属性,如下所示:
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
array.length = 4;
console.log(array); // Result: [0, 1, 2, 3]
注意,这个技巧只适用于 array.length
,不适用于的其他具有 length
属性的类型(如字符串或函数),也不用于 Set.prototype.size
。
11.获取数组的后几项元素
ARRAYS
数组方法 slice()
可以接受负整数,如果这么操作,它将从数组的末尾而不是开头截取值。
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(array.slice(-1)); // Result: [9]
console.log(array.slice(-2)); // Result: [8, 9]
console.log(array.slice(-3)); // Result: [7, 8, 9]
12.格式化JSON代码
JSON
最后,你以前可能使用过JSON.stringify
,但你是否意识到它也可以帮助缩进JSON 对象 ?
stringify()
方法接受两个可选参数:一个replacer
——如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为null或者未提供,则对象所有的属性都会被序列化。一个space
值。
space
参数接受一个整数,表示需要的空格数或一个字符串(如'\t'
来插入制表符),这可以使读取获取的JSON数据变得容易得多。
console.log(JSON.stringify({ alpha: 'A', beta: 'B' }, null, '\t'));
// Result:
// '{
// "alpha": A,
// "beta": B
// }'
总的来说,我希望你发现这些技巧和我第一次发现它们时一样有用。
原文链接:https://medium.com/@bretcameron/12-javascript-tricks-you-wont-find-in-most-tutorials-a9c9331f169d