JavaScript 常用简写技术

随着新 ECMAScript 标准的普及,许多曾经的 JavaScript 常见写法可以用更简单清楚的语法重构。本文做了一个简单的整理。

三元操作符

当想写 if...else 语句时,使用三元操作符来代替。

1
2
3
4
5
6
7
8
const x = 20;
let answer;

if (x > 10) {
answer = "is greater";
} else {
answer = "less than 10";
}

简写:

1
const answer = x > 10 ? "greater than 10" : "less than 10";

if 语句也可以像这样嵌套:

1
const answer = x > 10 ? "greater than 10" : x < 5 ? "less than 5" : "between 5 and 10";

短路求值简写方式

当给一个变量赋值时,你可能想要确定值不是 nullundefined 或空值。可以写一个多重条件的 if 语句:

1
2
3
if (variable1 !== null || variable1 !== undefined || variable1 !== "") {
let variable2 = variable1;
}

或者可以使用短路求值方法:

1
const variable2 = variable1 || "new";

另一个例子:

1
2
3
4
5
6
let dbHost;
if (process.env.DB_HOST) {
dbHost = process.env.DB_HOST;
} else {
dbHost = "localhost";
}

简写:

1
const dbHost = process.env.DB_HOST || "localhost";

声明变量简写方法

1
2
3
let x;
let y;
let z = 3;

简写方法:

1
let x, y, z = 3;

if 存在条件简写方法

1
if (likeJavaScript === true)

简写:

1
if (likeJavaScript)

只有 likeJavaScript 是真值时,二者语句才相等。
如果判断值不是真值,则可以这样:

1
2
3
4
let a;
if (a !== true) {
// do something...
}

简写:

1
2
3
4
let a;
if (!a) {
// do something...
}

循环简写方法

1
2
3
4
5
const fruits = ['mango', 'peach', 'banana'];
for (let i = 0; i < fruits.length; i++) {
let fruit = fruits[i];
// ...
}

简写:

1
2
3
for (let fruit of fruits) {
// ...
}

也可以使用 Array.forEach

1
2
3
4
5
6
7
8
function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[2] = 9

十进制指数

当需要写数字带有很多零时(如 1000000),可以采用指数(1e6)来代替这个数字:

1
for (let i = 0; i < 1000000; i++) {}

简写:

1
2
3
4
5
6
7
8
for (let i = 0; i < 1e7; i++) {}
// 下列等式都成立
1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;

对象属性简写

如果属性名与键名相同,则可以采用 ES6 的方法:

1
2
const x = 1920, y = 1080;
const obj = { x: x, y: y };

简写:

1
const obj = { x, y };

箭头函数简写

传统函数编写方法很容易让人理解和编写,但是当嵌套在另一个函数中,则这些优势就荡然无存。

1
2
3
4
5
6
7
8
9
10
11
function sayHello(name) {
console.log("Hello", name);
}

setTimeout(function() {
console.log("Loaded");
}, 2000);

list.forEach(function(item) {
console.log(item);
});

简写:

1
2
3
4
5
sayHello = name => console.log("Hello", name);

setTimeout(() => console.log("Loaded"), 2000);

list.forEach(item => console.log(item));

需要注意的是,箭头函数的 this 与用 function 关键字声明的函数不同,因此两者不完全等价。

隐式返回值简写

箭头函数同样用 return 关键字来返回其运行结果,但对于函数体只有一个语句的箭头函数,能隐式返回其值。正如前面的例子,箭头函数的大括号 {}return 语句都省略了。如果返回值包括多行语句(例如一个对象),则需要使用 () 包围函数体,避免语法错误。

1
2
3
4
5
6
7
function calcCircumference(diameter) {
return Math.PI * diameter;
}

const func = function() {
return { foo: 1 };
};

简写:

1
2
3
4
5
calcCircumference = diameter => (
Math.PI * diameter;
)

const func = () => ({ foo: 1 });

默认参数值

为了给函数中参数传递默认值,通常使用 if 语句来编写,但是使用 ES6 定义默认值,则会很简洁:

1
2
3
4
5
6
7
function volume(l, w, h) {
if (w === undefined)
w = 3;
if (h === undefined)
h = 4;
return l * w * h;
}

简写:

1
2
3
volume = (l, w = 3, h = 4) => (l * w * h);

volume(2) //output: 24

JavaScript 中如果没有向函数参数传递值,则默认为 undefined。有时为了判断参数是否传入,可以使用 if 语句来抛出异常。

1
2
3
4
5
6
function foo(bar) {
if (bar === undefined) {
throw new Error("Missing parameter!");
}
return bar;
}

这同样可以利用默认参数简写:

1
2
3
4
5
6
7
mandatory = () => {
throw new Error("Missing parameter!");
}

foo = (bar = mandatory()) => {
return bar;
}

模板字符串

传统的 JavaScript 语言,输出模板通常是这样写的:

1
2
3
const welcome = "You have logged in as " + first + " " + last + ".";

const db = "http://" + host + ":" + port + "/" + database;

ES6 可以使用反引号和 ${} 构成的模板字符串:

1
2
3
const welcome = `You have logged in as ${first} ${last}`;

const db = `http://${host}:${port}/${database}`;

模版字符串中的换行符也将得到保留,因此可以直接写多行字符串。

有时你会需要使用 + 来拼接输出多行字符串:

1
2
3
4
const lorem = "Lorem ipsum dolor sit amet, consectetur\n"
+ "adipisicing elit, sed do eiusmod tempor incididunt\n"
+ "ut labore et dolore magna aliqua. Ut enim ad minim\n"
+ "veniam, quis nostrud exercitation ullamco laboris.";

使用模板字符串,则可以达到简写作用:

1
2
3
4
const lorem = `Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris.`;

解构赋值简写方法

在 Web 框架中,经常需要从组件和 API 之间来回传递数组或对象字面形式的数据,然后需要解构它

1
2
3
4
5
6
7
8
9
const observable = require("mobx/observable");
const action = require("mobx/action");
const runInAction = require("mobx/runInAction");

const store = this.props.store;
const form = this.props.form;
const loading = this.props.loading;
const errors = this.props.errors;
const entity = this.props.entity;

简写:

1
2
3
import { observable, action, runInAction } from "mobx";

const { store, form, loading, errors, entity } = this.props;

你也可以分配不同的变量名:

1
2
const { store, form, loading, errors, entity: contact } = this.props;
//最后一个变量名为contact

Array.find 简写

想从数组中查找某个值,则需要循环。在 ES6 中,find() 函数能实现同样效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
const pets = [
{ type: "Dog", name: "Max" },
{ type: "Cat", name: "Karl" },
{ type: "Dog", name: "Tommy" },
];

function findDog(name) {
for (let i = 0; i < pets.length; ++i) {
if (pets[i].type === "Dog" && pets[i].name === name) {
return pets[i];
}
}
}

简写:

1
2
pet = pets.find(pet => pet.type === "Dog" && pet.name === "Tommy");
console.log(pet); // { type: "Dog", name: "Tommy" }

Object[key] 简写

考虑一个验证函数

1
2
3
4
5
6
7
8
function validate(values) {
if (!values.first)
return false;
if (!values.last)
return false;
return true;
}
console.log(validate({ first: "Bruce", last: "Wayne" })); // true

假设当需要不同域和规则来验证,能否编写一个通用函数在运行时确认?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 对象验证规则
const schema = {
first: {
required: true
},
last: {
required: true
}
}
// 通用验证函数
const validate = (schema, values) => {
for (field in schema) {
if (schema[field].required) {
if (!values[field]) {
return false;
}
}
}
return true;
}
console.log(validate(schema, { first: "Bruce" })); // false
console.log(validate(schema, { first: "Bruce", last: "Wayne" })); // true

现在可以有适用于各种情况的验证函数,不需要为每种情况单独编写了。

双重非位运算简写

双重非运算操作符可以用来代替 Math.floor(),其优势在于运行更快。

1
Math.floor(4.9) === 4  //true

简写

1
~~4.9 === 4  //true

幂运算简写

曾经幂运算需要通过 Math.pow 完成

1
2
3
Math.pow(2, 3); // 8
Math.pow(2, 2); // 4
Math.pow(4, 3); // 64

现在则可以使用 ** 运算符

1
2
3
2 ** 3 // 8
2 ** 4 // 4
4 ** 3 // 64

本文转载自:19 个 JavaScript 常用的简写技术

拓展阅读:25+ JavaScript Shorthand Coding Techniques