本文整理了一系列实用的 JavaScript 编码技巧,涵盖 ES6 及更高版本特性。内容涉及三元运算符、短路求值、变量声明、数组遍历、对象简写、箭头函数、默认参数、模板字符串、解构赋值、扩展运算符、数组查找及位运算等。通过对比传统写法与现代简写,帮助开发者提升代码简洁性与执行效率。
三元操作符与短路求值
三元操作符
当使用 if...else 语句时,三元操作符是一种节省代码的有效方式。
const x = 20;
let big;
if (x > 10) {
big = true;
} else {
big = false;
}
//这样写...
const big = x > 10 ? true : false;
短路求值(Short-circuit Evaluation)
在将一个变量值赋给另一个变量时,你可能需要确保源变量不为 null、undefined 或空字符串。你可以编写包含多个条件的 if 语句,或者利用短路求值来实现。
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
let variable2 = variable1;
}
// 这样写
const variable2 = variable1 || 'new';
不要轻信理论,请先通过测试验证(可将下方代码粘贴至 ES6 控制台运行)
let variable1;
let variable2 = variable1 || '';
console.log(variable2 === ''); // true
variable1 = 'foo';
variable2 = variable1 || '';
console.log(variable2); // foo
变量声明与存在性检查
变量声明
在函数内部声明多个变量时,使用逗号分隔符同时声明可以节省大量时间和空间:
let x;
let y;
let x = 3;
// or
let x, y, z = 3;
存在性检查
这看似微不足道,但值得注意。在进行“是否存在”检查时,有时可以省略赋值操作符。
if (likeJavaScript === true)
//or
if (likeJavaScript)
注:这两种方法并不完全等价。简写检查只要变量值在 JavaScript 中被判定为真(truthy),条件即通过。
这是另一个示例:如果变量 a 不为 true,则执行后续操作。
let a;
if (a !== true) {
// do something ...
}
//or
let a;
if (!a) {
// do something ...
}
循环与数组遍历优化
JavaScript 的 for 循环
如果你希望仅使用原生 JavaScript,而不依赖 jQuery 或 Lodash 等外部库,这个小技巧非常有用。
for (let i = 0; i < allImgs.length; i++)
//or
for (let index in allImgs)
Array.forEach 简写:
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
对象属性与箭头函数
对象属性
定义对象字面量(Object literals)让 JavaScript 开发更加便捷。ES6 提供了一种更简单的对象属性赋值方式。如果属性名与变量名相同,可以使用以下简写形式。
const obj = {x: x, y: y};
//or
const obj = {x, y};
箭头函数
传统函数易于阅读和编写,但在嵌套函数中调用其他函数时,代码可能会变得冗长且令人困惑。
function sayHello(name) {
console.log('Hello', name);
}
setTimeout(function() {
console.log('Loaded')
}, 2000);
list.forEach(function(item){
console.log(item)
})
//or
sayHello = name => console.log('Hello', name);
setTimeout(() => console.log('Loaded'), 2000);
list.forEach(item => console.log(item));
隐式返回
return 是函数中常用的关键字,用于返回最终结果。箭头函数支持单语句的隐式返回(此时必须省略花括号 {} 以省略 return 关键字)。
如果返回的是多行语句(例如对象字面量),必须在函数体内使用圆括号 () 而非花括号。这样可以确保代码块作为单独语句返回。
function calcCircumference(diameter) {
return Math.PI * diameter
}
//or
calcCircumference = diameter => (
Math.PI * diameter;
)
默认参数与模板字符串
默认参数值
你可以使用 if 语句来定义函数参数的默认值。在 ES6 中,可以直接在函数声明中定义默认参数。
function volume(l, w, h) {
if (w === undefined)
w = 3;
if (h === undefined)
h = 4;
return l * w * h;
}
//or
volume = (l, w = 3, h = 4) => (l * w * h);
volume(2); // 24
模板字符串(Template Literals)
是否厌倦了使用 + 号连接多个变量来拼接字符串?是否有更简单的方法?如果使用 ES6,你很有幸。在 ES6 中,只需使用反引号(`)和 ${},并将变量置于大括号内即可。
const welcome = 'You have logged in as' + first + ' ' + last + '.';
const db = 'http://' + host + ':' + port + '/' + database;
//or
const welcome = `You have logged in as ${first} ${last}`;
const db = `http://${host}:${port}/${database}`;
解构赋值与扩展运算符
解构赋值(Destructuring Assignment)
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;
//or
import {observable, action, runInAction} from 'mobx';
const {store, form, loading, errors, entity} = this.props;
你甚至可以自定义变量名:
const {store, form, loading, errors, entity:contact} = this.props; //通过 : 号来重命名
扩展运算符(Spread Operator)
扩展运算符是 ES6 引入的特性,使 JavaScript 代码更高效且有趣。它可以替代某些数组功能。扩展运算符由三个点 (...) 表示。
// Joining arrays
const odd = [1, 3, 5];
const nums = [2, 4, 6].concat(odd);
// cloning arrays
const arr = [1, 2, 3, 4];
const arr2 = arr.slice();
//or
// Joining arrays
const odd = [1, 3, 5];
const nums = [2, 4, 6, ...odd];
console.log(nums); // [2, 4, 6, 1, 3, 5]
// cloning arrays
const arr = [1, 2, 3, 4];
const arr2 = [...arr];
与 concat() 函数不同,使用扩展运算符可以将一个数组插入到另一个数组的任意位置。
const odd = [1, 3, 5];
const nums = [2, ...odd, 4, 6];
此外,它还可以用作解构符:
const {a, b, ...z} = {a: 1, b: 2, c: 3, d: 4};
console.log(a); // 1
console.log(b); // 2
console.log(z); // {c: 3, d: 4}
强制参数
function foo(bar) {
if (bar === undefined) {
throw new Error('Missing parameter!');
}
return bar;
}
//or
mandatory = () => {
throw new Error('Missing parameter!');
}
foo = (bar = mandatory()) => {
return bar;
}
数组查找与动态属性访问
Array.find
如果你以前编写过查找函数,可能会使用 for 循环。在 ES6 中,你可以使用数组的新方法 find()。
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];
}
}
}
// or
pet = pets.find(pet => pet.type === 'Dog' && pet.name === 'Tommy');
console.log(pet); // {type: 'Dog', name: 'Tommy'}
Object[key]
你知道 Foo.bar 也可以写成 Foo[bar] 吧。起初,这似乎没有理由。然而,这种符号允许你编写可重用的代码块。
function validate(values) {
if (!values.first)
return false;
if (!values.last)
return false;
return true;
}
console.log(validate({first: 'Bruce', last: 'Wayne'})); // true
该函数可以正常工作。然而,需要考虑这样一个场景:有多种表单需要应用验证,且不同字段有不同的规则。在运行时很难创建一个通用的验证功能。
// object validation rules
const schema = {
first: {
required: true
},
last: {
required: true
}
}
// universal validation function
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
现在,我们有一个验证函数,可以在各种表单中重用,而无需为每个不同的功能定制单独的验证函数。
位运算与性能优化
双重按位非(Double Bitwise NOT)
如果你是 JavaScript 新手,可能永远不会在任何地方使用按位运算符(Bitwise Operator)。此外,如果你不处理二进制 0 和 1,就更不会想到使用它。
然而,一个非常实用的用例是双重位操作符。你可以用它替代 Math.floor()。双重按位非运算符具有显著优势,它执行相同操作的速度要快得多。你可以在此处阅读更多关于位运算符的知识。
Math.floor(4.9) === 4; // true
//or
~~4.9 === 4; //true
以上就是 JavaScript 编码小技巧分享的详细内容,更多关于 JavaScript 编码技巧的资料请关注本站其它相关文章!