对于任何 JavaScript 开发人员来说,这都是必读之书。我们编写了这份指南,介绍多年来积累的 JavaScript 简写编码技术。为了帮助您了解正在发生的事情,我们提供了全写版本,以提供一些编码视角。
- 三元运算符 {#1theternaryoperator}
当您想if..else
仅用一行编写语句时,这是一个很好的代码节省器。
普通手写:
const x = 20;
let answer;
if (x > 10) {
answer = "greater than 10";
} else {
answer = "less than 10";
}
速记:
const answer = x > 10 ? "greater than 10" : "less than 10";
您还可以if
像这样嵌套语句:
const answer = x > 10 ? "greater than 10" : x < 5 ? "less than 5" : "between 5 and 10";
- 短路求值简写 {#2shortcircuitevaluationshorthand}
将变量值赋给另一个变量时,您可能希望确保源变量不为 null、未定义或空。您可以编写if
包含多个条件的长语句,也可以使用短路求值。
普通手写:
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
let variable2 = variable1;}
速记:
const variable2 = variable1 || 'new';
不相信吗?自己测试一下(将以下代码粘贴到es6console中):
let variable1;
let variable2 = variable1 || 'bar';
console.log(variable2 === 'bar'); // prints true
variable1 = 'foo';
variable2 = variable1 || 'bar';
console.log(variable2); // prints foo
请注意,如果您设置variable1
为false
或,则会分配0
值。bar
- 声明变量简写 {#3declaringvariablesshorthand}
在函数开头声明变量赋值是一种很好的做法。这种简便方法可以在同时声明多个变量时节省大量时间和空间。
普通手写:
let x;
let y;
let z = 3;
速记:
let x, y, z=3;
- 如果存在速记 {#4ifpresenceshorthand}
这可能微不足道,但值得一提。在进行"if
检查"时,有时可以省略赋值运算符。
普通手写:
if (likeJavaScript === true)
速记:
if (likeJavaScript)
注意:这两个例子并不完全相等,因为只要
likeJavaScript
是真值,简写检查就会通过。
这是另一个示例。如果a
不等于 true,则执行某些操作。
普通手写:
let a;
if ( a !== true ) {
// do something...
}
速记:
let a;
if ( !a ) {
// do something...
}
- JavaScript For 循环简写 {#5javascriptforloopshorthand}
如果您想要纯 JavaScript 并且不想依赖 jQuery 或 lodash 等外部库,这个小技巧非常有用。
普通手写:
const fruits = ['mango', 'peach', 'banana'];
for (let i = 0; i < fruits.length; i++)
速记:
for (let fruit of fruits)
如果您只是想访问索引,请执行以下操作:
for (let index in fruits)
如果你想访问文字对象中的键,这也有效:
const obj = {continent: 'Africa', country: 'Kenya', city: 'Nairobi'}
for (let key in obj)
console.log(key) // output: continent, country, city
Array.forEach 的简写:
function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = 9
- 短路评估 {#6shortcircuitevaluation}
如果预期参数为空或未定义,我们无需编写六行代码来分配默认值,而是可以简单地使用短路逻辑运算符,仅用一行代码即可完成相同的操作。
普通手写:
let dbHost;
if (process.env.DB_HOST) {
dbHost = process.env.DB_HOST;
} else {
dbHost = 'localhost';
}
速记:
const dbHost = process.env.DB_HOST || 'localhost';
- 十进制底数指数 {#7decimalbaseexponents}
您可能已经见过这个。它本质上是一种不带尾随零的奇特数字书写方式。例如,1e7 本质上表示 1 后面跟着 7 个零。它表示十进制基数(JavaScript 将其解释为浮点类型),等于 10,000,000。
普通手写:
for (let i = 0; i < 10000; i++) {}
速记:
for (let i = 0; i < 1e7; i++) {}
// All the below will evaluate to true
1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;
- 对象属性简写 {#8objectpropertyshorthand}
在 JavaScript 中定义对象字面量让生活变得更加轻松。ES6 提供了一种更简单的方法来为对象分配属性。如果变量名与对象键相同,则可以利用简写符号。
普通手写:
const x = 1920, y = 1080;
const obj = { x:x, y:y };
速记:
const obj = { x, y };
- 箭头函数简写 {#9arrowfunctionsshorthand}
经典函数以其简单的形式易于阅读和编写,但一旦开始将它们嵌套在其他函数调用中,它们就会变得有点冗长和令人困惑。
普通手写:
function sayHello(name) {
console.log('Hello', name);
}
setTimeout(function() {
console.log('Loaded')
}, 2000);
list.forEach(function(item) {
console.log(item);
});
速记:
sayHello = name => console.log('Hello', name);
setTimeout(() => console.log('Loaded'), 2000);
list.forEach(item => console.log(item));
需要注意的是,this
箭头函数内部的值的确定方式与普通函数不同,因此这两个示例并不完全等同。有关更多详细信息,请参阅有关箭头函数语法的文章。
- 隐式返回简写 {#10implicitreturnshorthand}
Return 是我们经常用来返回函数最终结果的关键字。具有单个语句的箭头函数将隐式返回其求值的结果(函数必须省略括号 ( {}
) 才能省略 return 关键字)。
要返回多行语句(例如对象文字),必须使用()
而不是{}
来包装函数体。这可确保将代码评估为单个语句。
普通手写:
function calcCircumference(diameter) {
return Math.PI * diameter
}
速记:
calcCircumference = diameter => (
Math.PI * diameter;
)
- 默认参数值 {#11defaultparametervalues}
您可以使用if
语句来定义函数参数的默认值。在 ES6 中,您可以在函数声明本身中定义默认值。
普通手写:
function volume(l, w, h) {
if (w === undefined)
w = 3;
if (h === undefined)
h = 4;
return l * w * h;
}
速记:
volume = (l, w = 3, h = 4 ) => (l * w * h);
volume(2) //output: 24
- 模板字符串 {#12templateliterals}
您是否厌倦了将' + '
多个变量连接到一个字符串中?难道没有更简单的方法吗?如果您能够使用 ES6,那么您很幸运。您需要做的就是使用反引号并将${}
变量括起来。
普通手写:
const welcome = 'You have logged in as ' + first + ' ' + last + '.'
const db = 'http://' + host + ':' + port + '/' + database;
速记:
const welcome = `You have logged in as ${first} ${last}`;
const db = `http://${host}:${port}/${database}`;
- 解构赋值简写 {#13destructuringassignmentshorthand}
如果您正在使用任何流行的 Web 框架,则很有可能会使用数组或对象文字形式的数据在组件和 API 之间传递信息。一旦数据对象到达组件,您就需要对其进行解包。
普通手写:
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;
速记:
import { observable, action, runInAction } from 'mobx';
const { store, form, loading, errors, entity } = this.props;
您甚至可以指定自己的变量名称:
const { store, form, loading, errors, entity:contact } = this.props;
- 多行字符串简写 {#14multilinestringshorthand}
如果你发现自己需要在代码中编写多行字符串,你可以这样编写:
普通手写:
const lorem = 'Lorem ipsum dolor sit amet, consectetur\n\t'
+ 'adipisicing elit, sed do eiusmod tempor incididunt\n\t'
+ 'ut labore et dolore magna aliqua. Ut enim ad minim\n\t'
+ 'veniam, quis nostrud exercitation ullamco laboris\n\t'
+ 'nisi ut aliquip ex ea commodo consequat. Duis aute\n\t'
+ 'irure dolor in reprehenderit in voluptate velit esse.\n\t'
但还有更简单的方法。只需使用反引号即可。
速记:
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
nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse.`
- 扩展运算符简写 {#15spreadoperatorshorthand}
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()
速记:
// 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];
您还可以将扩展运算符与 ES6 解构符号结合起来:
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 }
- 强制参数简写 {#16mandatoryparametershorthand}
默认情况下,undefined
如果函数参数未传递值,JavaScript 会将其设置为。其他一些语言会抛出警告或错误。要强制参数分配,您可以使用语句if
在 if 时抛出错误undefined
,或者您可以利用"强制参数简写"。
普通手写:
function foo(bar) {
if(bar === undefined) {
throw new Error('Missing parameter!');
}
return bar;
}
速记:
mandatory = () => {
throw new Error('Missing parameter!');
}
foo = (bar = mandatory()) => {
return bar;
}
- Array.find 简写 {#17arrayfindshorthand}
如果您曾经被要求用纯 JavaScript 编写 find 函数,那么您可能会使用循环。在 ES6 中,引入了for
一个名为的新数组函数。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];
}
}
}
速记:
pet = pets.find(pet => pet.type ==='Dog' && pet.name === 'Tommy');
console.log(pet); // { type: 'Dog', name: 'Tommy' }
- 对象 [key] 简写 {#18objectkeyshorthand}
你知道吗?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
现在我们有一个验证函数,可以在所有表单中重复使用,而不需要为每个表单编写自定义验证函数。
- 双重按位非简写 {#19doublebitwisenotshorthand}
位运算符是您在初级 JavaScript 教程中学习的功能之一,但您从未在任何地方实现过它们。此外,如果您不处理二进制,谁会想使用 1 和 0?
但是,双位非运算符有一个非常实用的用例。您可以用它代替Math.floor()
。双位非运算符的优点是它执行相同操作的速度要快得多。您可以在此处阅读有关位运算符的更多信息。
普通手写:
Math.floor(4.9) === 4 //true
速记:
~~4.9 === 4 //true
- 指数幂速记 {#20exponentpowershorthand}
数学指数幂函数的简写:
普通手写:
Math.pow(2,3); // 8
Math.pow(2,2); // 4
Math.pow(4,3); // 64
速记:
2**3 // 8
2**4 // 4
4**3 // 64
- 将字符串转换为数字 {#21convertingastringintoanumber}
有时您的代码会收到字符串格式的数据,但需要以数字格式进行处理。这没什么大不了的,我们可以进行快速转换。
普通手写:
const num1 = parseInt("100");
const num2 = parseFloat("100.01");
速记:
const num1 = +"100"; // converts to int data type
const num2 = +"100.01"; // converts to float data type
- 对象属性赋值 {#22objectpropertyassignment}
考虑以下一段代码:
let fname = { firstName : 'Black' };
let lname = { lastName : 'Panther'}
如何将它们合并为一个对象?一种方法是编写一个函数,将数据从第二个对象复制到第一个对象。不幸的是,这可能不是你想要的------你可能需要创建一个全新的对象而不改变任何现有对象。最简单的方法是使用Object.assign
ES6 中引入的函数:
let full_names = Object.assign(fname, lname);
您还可以使用 ES8 中引入的对象销毁符号:
let full_names = {...fname, ...lname};
可以合并的对象属性数量没有限制。如果您确实有具有相同属性名称的对象,则将按照合并顺序覆盖值。
- 按位索引简写 {#23bitwiseindexofshorthand}
使用数组执行查找时,该indexOf()
函数用于检索要查找的项目的位置。如果未找到该项目,则-1
返回值。在 JavaScript 中,0
被视为"假",而大于或小于的数字0
被视为"真"。因此,必须像这样编写正确的代码。
普通手写:
if(arr.indexOf(item) > -1) { // Confirm item IS found
}
if(arr.indexOf(item) === -1) { // Confirm item IS NOT found
}
速记:
if(~arr.indexOf(item)) { // Confirm item IS found
}
if(!~arr.indexOf(item)) { // Confirm item IS NOT found
}
运算bitwise(~)
符将返回除 之外的任何内容的真值-1
。否定它就像执行 一样简单!~
。或者,我们也可以使用以下includes()
函数:
if(arr.includes(item)) { // Returns true if the item exists, false if it doesn't
}
- 对象.entries() {#24objectentries}
这是 ES8 中引入的功能,允许你将文字对象转换为键/值对数组。请参阅以下示例:
const credits = { producer: 'John', director: 'Jane', assistant: 'Peter' };
const arr = Object.entries(credits);
console.log(arr);
/** Output:
[ [ 'producer', 'John' ],
[ 'director', 'Jane' ],
[ 'assistant', 'Peter' ]
]
**/
- 对象.值() {#25objectvalues}
这也是 ES8 中引入的新功能,其功能与 类似Object.entries()
,但没有关键部分:
const credits = { producer: 'John', director: 'Jane', assistant: 'Peter' };
const arr = Object.values(credits);
console.log(arr);
/** Output:
[ 'John', 'Jane', 'Peter' ]
**/
关于 JavaScript 简写编码技术的常见问题解答 {#faqsaboutjavascriptshorthandcodingtechniques}
JavaScript 中最常见的一些简写技巧有哪些? {#faq-question-1704744177959}
JavaScript 简写技术是一种编写更高效、更简洁的代码的方法。一些最常见的简写技术包括三元运算符(一种编写 if-else 语句的更短方法)和空值合并运算符(如果第一个参数不为空或未定义,则返回第一个参数)。其他常见的简写技术包括可选链接运算符(允许您访问深层嵌套的对象属性而无需检查每个属性是否存在)和逻辑或赋值(||=),仅当变量为空时才为变量赋值。
在使用 JavaScript 编码时,速记技术如何节省时间? {#faq-question-1704744197805}
速记技巧可以显著减少您需要编写的代码量,使您的代码更易读、更易于维护。它们还可以让您的代码运行得更快,因为代码越少,处理时间就越少。此外,速记技巧可以帮助防止错误,因为它们通常包含内置的错误检查。
在 JavaScript 中使用简写技术有什么缺点吗? {#faq-question-1704744212218}
虽然简写技巧可以使您的代码更高效、更易读,但它们也可能使初学者更难理解。如果您所在的团队由经验不足的开发人员组成,您可能需要花费额外的时间来解释这些技巧的工作原理。此外,某些简写技巧可能不受旧版浏览器的支持,因此您需要确保您的代码与您的受众使用的浏览器兼容。
你能提供一些如何在 JavaScript 中使用简写技巧的例子吗? {#faq-question-1704744226657}
当然,这里有几个例子。要使用三元运算符,您可以编写 `let result = (a > b) ? 'a is greater' : 'b is greater';`,而不是使用完整的 if-else 语句。要使用空值合并运算符,您可以编写 `let result = a ?? 'default';`,如果变量为空或未定义,则为其分配默认值。
有哪些资源可以了解更多有关 JavaScript 简写技巧的知识? {#faq-question-1704744241783}
有许多在线资源可用于学习 JavaScript 简写技术。Mozilla 开发者网络 (MDN) 有关于 JavaScript 的全面文档,其中包括关于简写技术的部分。您还可以在 SitePoint、Plain English 和 Geeks for Geeks 等网站上找到教程和文章。
如何练习使用 JavaScript 中的速记技巧? {#faq-question-1704744254304}
练习使用简写技巧的最佳方式是将它们融入到您自己的代码中。尝试使用这些技巧重写一些现有代码,看看它如何影响代码的可读性和效率。您还可以尝试在 HackerRank 或 LeetCode 等网站上解决编码挑战,这可以帮助您在各种情况下熟练掌握这些技巧。
其他编程语言是否使用简写技术? {#faq-question-1704744275621}
是的,许多其他编程语言都使用了简写技术,包括 Python、Ruby 和 C++。虽然具体技术和语法可能有所不同,但基本原则是相同的:编写更高效、更易读的代码。
我如何才能记住 JavaScript 中的所有不同简写技巧? {#faq-question-1704744290335}
记住所有不同的速记技巧可能很有挑战性,尤其是如果你刚接触 JavaScript。一种策略是专注于一次学习一种技巧,并练习使用它,直到它成为你的第二天性。你也可以随身携带一份速记表,以便快速参考。
简写技术会影响我的 JavaScript 代码的性能吗? {#faq-question-1704744305647}
是的,简写技术可以通过减少需要处理的代码量来提高代码的性能。但是,对性能的影响通常很小,更重要的是要专注于编写清晰、可维护的代码。
有哪些速记技巧被认为是不好的做法? {#faq-question-1704744321074}
虽然大多数简写技术都被认为是良好做法,但有些技术可能会造成混淆或导致意外行为。例如,使用"=="运算符进行相等性检查可能会导致意外的类型强制,因此通常建议改用"==="运算符。同样,如果您不熟悉"&&"运算符的工作原理,则使用"&&"运算符进行条件执行可能会造成混淆。在代码中使用简写技术之前,了解其工作原理始终很重要。