对于任何基于 JavaScript 编程的开发人员来说,都有必要认证阅读一下这篇文章。 我写的这篇文章是学习 JavaScript 简写编码技巧的重要参考资料,这些技巧都是我多年学习和总结出来的。 为了有助于理解这些简写编码技巧,我也给出了相关的编码观点。
2019年8月25日:本文已更新,以根据最新规范添加新的速记技巧。
1. 三元操作符
当你想在一行代码中写一个 if..else
语句时,这是一个很好的节省代码的方式。
普通写法:
const x = 20; let answer; if (x > 10) { answer = 'is greater'; } else { answer = 'is lesser'; }
简写:
const answer = x > 10 ? 'greater than 10' : 'less than 10';
你也可以像这样嵌套 if 语句:
const answer = x > 10 ? " greater than 10" : x
2. 缩短求值简写
将变量值分配给另一个变量时,你可能需要确保源变量不为 null、undefined 或者不为空。你可以使用多个条件写一个很长的 if
语句,也可以使用缩短求值的简写办法。
普通写法:
if (variable1 !== null || variable1 !== undefined || variable1 !== '') { let variable2 = variable1; }
简写:
const variable2 = variable1 || 'new';
不相信我的话?你可以自己测试(在 es6console 中粘贴以下代码):
let variable1; let variable2 = variable1 || ''; console.log(variable2 === ''); // prints true variable1 = 'foo'; variable2 = variable1 || ''; console.log(variable2); // prints foo
请注意,如果将variable1
设置为false
或0
,bar
则将分配值。
3. 变量声明速简写
在函数开始处声明变量并赋值是一个很好的习惯。这种简写方法可以同时声明多个变量,为您节省大量的时间和空间。
普通写法:
let x; let y; let z = 3;
简写:
let x, y, z=3;
4. If 条件为真的简写
这可能是微不足道的,但值得一提。在做 “ if 检查” 时,碰到条件为真时,比较运算操作可以省略。
普通写法:
if (likeJavaScript === true)
简写:
if (likeJavaScript)
注意: 这两个例子并不是完全相等,只要
likeJavaScript
变量是一个 真值,该表达式就是成立的。
还有另一个例子。如果 “a” 不等于 true
,如下:
普通写法:
let a; if ( a !== true ) { // do something... }
简写:
let a; if ( !a ) { // do something... }
5. JavaScript for 循环简写
如果你只想要简单的 JavaScript ,而不是依赖外部库,如jQuery或lodash,那这个小技巧会非常有用。
普通写法:
for (let i = 0; i < allImgs.length; i++)
简写:
for (let index of 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
6. 缩短求值
我们可以简单地使用缩短逻辑运算符,只用一行代码完成相同的事情,而不是写 6 行代码来分配缺省值。
普通写法:
let dbHost; if (process.env.DB_HOST) { dbHost = process.env.DB_HOST; } else { dbHost = 'localhost'; }
简写:
const dbHost = process.env.DB_HOST || 'localhost';
7. 十进制数指数
你可能见过这个这种写法。它本质上是一种比较花哨的数字表示法,省去了后面尾随的一堆零。例如,1e7
实际上表示 1
后面跟着 7
个零。它表示一个十进制基数指数 (JavaScript解释为浮点类型),等于10,000,000。
普通写法:
for (let i = 0; i < 10000; i++) {}
简写:
for (let i = 0; i < 1e7; i++) {} // 以下将全部求值为 true 1e0 === 1; 1e1 === 10; 1e2 === 100; 1e3 === 1000; 1e4 === 10000; 1e5 === 100000;
8. 对象属性简写
在 JavaScript 中定义对象字面量非常容易。ES6 提供了一种更简单的方法来将属性分配给对象。如果 name 和 key 名字相同,则可以利用简写符号。
普通写法:
const obj = { x:x, y:y };
简写:
const obj = { x, y };
9. 箭头函数简写
普通写法的函数很容易阅读和书写,但是一旦开始在其他函数调用中嵌套它们,它们就会变得有点冗长和混乱。
普通写法:
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
值的确定方式不同于普通写法的函数,所以这两个例子并不完全相同。有关更多详细信息,请参阅 这篇文章中的箭头函数语法 。
10. 隐式返回简写
我们经常使用 return 关键字来返回一个函数的最终结果。使用单条语句的箭头函数将隐式返回求值结果(该函数必须省略大括号({}
)才能省略 return
关键字)。
要返回多行表达式(如对象字面量),那么需要用 ()
而不是 {}
来包裹你的函数体。这样可以确保代码作为一个单独的表达式被求值返回。
普通写法:
function calcCircumference(diameter) { return Math.PI * diameter }
简写:
calcCircumference = diameter => ( Math.PI * diameter; )
11. 参数默认值
你可以使用 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
12. 模板字面量
你是不是已经厌倦了用 ' + '
来连接多个变量拼接成一个字符串?有没有更简单的方式来完成吗?如果你可以使用 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}`;
13. 解构赋值简写
如果你正在使用任何流行的 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;
14. 多行字符串简写
如果你曾经发现自己需要在代码中编写多行字符串,那么你将会这样写:
普通写法:
const lorem = 'Lorem ipsum dolor sit amet, consecteturnt' + 'adipisicing elit, sed do eiusmod tempor incididuntnt' + 'ut labore et dolore magna aliqua. Ut enim ad minimnt' + 'veniam, quis nostrud exercitation ullamco laborisnt' + 'nisi ut aliquip ex ea commodo consequat. Duis autent' + 'irure dolor in reprehenderit in voluptate velit esse.nt'
但是有一种更简单的方法。只需使用反引号。
简写:
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.`
15. 展开运算符简写
在ES6中引入的 展开运算符 有几个用例,使 JavaScript 代码更高效、更有趣。它可以用来替换某些数组函数。展开运算符写起来很简单,就是三个点。
普通写法:
// 拼接数组 const odd = [1, 3, 5]; const nums = [2 ,4 , 6].concat(odd); // 克隆数组 const arr = [1, 2, 3, 4]; const arr2 = arr.slice()
简写:
// 拼接数组 const odd = [1, 3, 5 ]; const nums = [2 ,4 , 6, ...odd]; console.log(nums); // [ 2, 4, 6, 1, 3, 5 ] // 克隆数组 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 }
16. 强制参数简写
默认情况下,如果 JavaScript 传递的值没赋值,它将设置函数参数为 undefined
。其他一些语言会抛出警告或错误。为了强制给参数赋值,如果参数没有定义的话,你可以使用 if
表达式抛出错误,或者可以可以利用强制参数简写。
普通写法:
function foo(bar) { if(bar === undefined) { throw new Error('Missing parameter!'); } return bar; }
简写:
mandatory = () => { throw new Error('Missing parameter!'); } foo = (bar = mandatory()) => { return bar; }
17. Array.find 简写
如果你曾经使用原生 JavaScript 写一个查找函数,你可能会使用 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]; } } }
简写:
pet = pets.find(pet => pet.type ==='Dog' && pet.name === 'Tommy'); console.log(pet); // { type: 'Dog', name: 'Tommy' }
18. 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
这个函数很好的实现了所需的功能。但是,考虑一个场景,在这个场景中,你有非常多的表单需要验证,但是需要使用不同的字段和规则。那么构建一个在运行时被配置的通用验证函数岂不是更好?
简写:
// 对象验证规则 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
现在创建了一个可以在所有的表单里重用的验证函数,而不必为每个表单单独写一个特定的验证函数。
19. 双位非运算符简写
位操作符是你在刚学习 JavaScript 时会学到的一个特性,但是如果你不处理二进制的话,基本上是从来都不会用上的。
但是,双位运算符有一个非常实用的使用场景:可以用来代替 Math.floor
。双位非运算符的优势在于它执行相同操作的速度更快。你可以在这里查看更多关于位运算符的知识。
普通写法:
Math.floor(4.9) === 4 //true
简写:
~~4.9 === 4 //true
注:按位运算符方法执行很快,当你执行数百万这样的操作非常适用,速度明显优于其他方法。但是代码的可读性比较差。还有一个特别要注意的地方,所有的按位运算都以带符号的32位整数进行。处理比较大的数字时(当数字范围超出 ±2^31?1 即:2147483647),会有一些异常情况。使用的时候明确的检查输入数值的范围。 具体可以查看 你可能不知道的 JavaScript 中数字取整:向上取整,向下取整,四舍五入,舍去小数
20.指数幂简写
数学指数幂函数的简写:
普通写法:
Math.pow(2,3); // 8 Math.pow(2,2); // 4 Math.pow(4,3); // 64
简写:
2**3 // 8 2**4 // 4 4**3 // 64
21.将字符串转换为数字
有时您的代码会接收到字符串格式的数据,但需要以数字格式进行处理。没什么大不了的,我们可以快速转换。
普通写法:
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
22. Object属性赋值
考虑以下代码:
let fname = { firstName : 'Black' }; let lname = { lastName : 'Panther'}
如何将它们合并成一个对象?一种方法是编写一个函数,将数据从第二个对象复制到第一个对象。不幸的是,这可能不是您想要的—您可能需要创建一个全新的对象而不改变任何现有对象。最简单的方法是使用ES6中引入的函数Object.assign
:
let full_names = Object.assign(fname, lname);
你也可以使用在ES8中引入的对象销毁符号:
let full_names = {...fname, ...lname};
可以合并的对象属性的数量没有限制。如果确实具有具有相同属性名称的对象,则值将按照它们被合并的顺序被覆盖。
23.速记按位索引
使用数组执行查找时,indexOf()函数用于检索要查找的项目的位置。如果找不到项目,则返回值-1。在JavaScript中,数字0被视为“falsy”,而大于或小于数字0被视为“truthy”。因此,必须像这样编写正确的代码。
普通写法:
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
以外的任何值返回一个truthy值。否定它就像做一样简单!~
。或者,我们也可以使用include()
函数:
if(arr.includes(item)) { // Returns true if the item exists, false if it doesn't }
24. Object.entries()
这是ES8中引入的一个特性,允许您将文字对象转换为键/值对数组。请看下面的例子:
const credits = { producer: 'John', director: 'Jane', assistant: 'Peter' }; const arr = Object.entries(credits); console.log(arr); /** Output: [ [ 'producer', 'John' ], [ 'director', 'Jane' ], [ 'assistant', 'Peter' ] ] **/
25. Object.values()
这也是ES8中引入的一个新特性,它执行与Object.entries()
类似的功能,但没有关键部分:
const credits = { producer: 'John', director: 'Jane', assistant: 'Peter' }; const arr = Object.values(credits); console.log(arr); /** Output: [ 'John', 'Jane', 'Peter' ] **/
26. 还有其他的小技巧?
我确实喜欢这些小技巧,希望能有更多关于这方面的 JavaScript 小技巧。如果你有这方面的技巧,欢迎留言分享!
原文链接:https://www.sitepoint.com/shorthand-javascript-techniques/