「这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战」
本文总结了一些js短写技巧,为了便于理解,同时附上了普通的长写版本代码。
1. 三元运算符
当我们编写 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";
我们还可以这样嵌套
const answer = x > 10 ? "greater than 10" : x < 5 ? "less than 5" : "between 5 and 10";
2.短路短写法
将变量值分配给另一个变量时,我们可能希望源变量不为null, undefined, 或者 empty。 我们可以编写带有多个条件的长 if 语句,也可以使用短路短写法。
普通长版本
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
let variable2 = variable1;
}
短写版本
const variable2 = variable1 || 'new';
可以用下面的代码测试
let variable1;
let variable2 = variable1 || 'bar';
console.log(variable2 === 'bar'); // 打印 true
variable1 = 'foo';
variable2 = variable1 || 'bar';
console.log(variable2); // 打印 foo
3.短写法声明变量
在函数的开头处声明变量赋值是一种很好的习惯。同时声明多个变量时,这种短写方法可以节省大量时间和空间。
长版本
let x;
let y;
let z = 3;
短写版本
let x, y, z=3;
4.if短写
可能这算不上什么技巧,但是还是值得提一下,if条件语句的比较运算符有的时候是可以省略的。 长版本
if (likeJavaScript == true)
短版本
if (likeJavaScript)
另外一些a不为true的例子
长版本
let a;
if ( a !== true ) {
// do something...
}
短版本
let a;
if ( !a ) {
// do something...
}
5.循环的短写法
如果只使用原生js不使用第三方库如jquery、lodash将会非常的有用。
长版本
const fruits = ['mango', 'peach', 'banana'];
for (let i = 0; i < fruits.length; i++)
短写版本
for (let fruit of fruits)
如果你只想访问index:
for (let index in fruits)
如果你只想访问对象字面量的key
const obj = {continent: 'Africa', country: 'Kenya', city: 'Nairobi'}
for (let key in obj)
console.log(key) // 输出: 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
6.短路
用6行代码完成,给变量赋值如果源变量为null或undefined则赋一个默认值的工作。 我们可以简单地使用短路逻辑运算符在一行代码中完成相同的工作。
长版本
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 个零。等于 10,000,000。
长版本
for (let i = 0; i < 10000; i++) {}
短写版本
for (let i = 0; i < 1e7; i++) {}
// 以下的等式都是成立的
1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;
8.对象属性短写
ES6 提供了一种更简单的方法来为对象分配属性。 如果变量名称与对象键名相同,则可以使用短写。
长版本
const x = 1920, y = 1080;
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) //输出: 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, 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.`
15.扩展运算符
ES6 中引入的扩展运算符,可以使 JavaScript 代码使用起来更加高效和有趣。 它可用于替换某些数组函数。
长版本
// 拼接 arrays
const odd = [1, 3, 5];
const nums = [2 ,4 , 6].concat(odd);
// 克隆 arrays
const arr = [1, 2, 3, 4];
const arr2 = arr.slice()
短写版本
// 拼接 arrays
const odd = [1, 3, 5 ];
const nums = [2 ,4 , 6, ...odd];
console.log(nums); // [ 2, 4, 6, 1, 3, 5 ]
// 克隆 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 }
16.强制传递参数短写
默认情况下,如果未传值,Js 会将函数参数设置为 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 编写 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];
}
}
}
短写版本
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
}
}
// 通用 validation 函数
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
借助于Object[key]语法,我们有了一个通用验证函数,可以在所有表单中重用,而无需为每个表单编写自定义验证函数。
19.双按位非(~)
按位运算符貌似很难找到使用它们的场景。如果不处理二进制,谁愿意与1和0打交道?
然而,双按位非(~)运算符有一个非常实用的用途。 可以将其用作 Math.floor()的替代品。 双按位非(~)运算符的优点是它执行相同操作的速度要快得多。
长版本
Math.floor(4.9) === 4 //true
短写版本
~~4.9 === 4 //true
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"; //转化为int格式
const num2 = +"100.01"; // 转化为float格式
22.对象属性分配
let fname = { firstName : 'Black' };
let lname = { lastName : 'Panther'}
你将如何将它们合并为一个对象? 一种方法是编写一个函数,将数据从第二个对象复制到第一个对象上。 不幸的是,这可能不是你想要的——你可能需要创建一个全新的对象而不改变任何现有对象。 最简单的方法是使用 ES6 中引入的 Object.assign 函数:
let full_names = Object.assign(fname, lname);
运用对象解构
let full_names = {...fname, ...lname};
可以合并的对象属性数量没有限制。 如果遇到具有相同属性名称的对象,则值将按照它们合并的顺序被覆盖。
23.按位非(~)
使用数组执行查找时,indexOf() 函数用于检索要查找的项目的位置。 如果未找到该项目,则返回值 -1。 在 JavaScript 中,0 被认为是“false”,而大于或小于 0 的数字被认为是“true”的。所以,必须小心翼翼的编写这样的代码。
长版本
if(arr.indexOf(item) > -1) { // item找到了
}
if(arr.indexOf(item) === -1) { // item 没有找到
}
短写版本
if(~arr.indexOf(item)) { // item找到了
}
if(!~arr.indexOf(item)) { // item 没有找到
}
除 -1 以外的任何值(~)运算符将返回类true值。如果觉得这不是很容易理解,当然,我们也可以使用 includes() 函数:
if(arr.includes(item)) {
}
24.Object.entries()
这是 ES8 中引入的一项功能,允许我们将对象字面量转换为键/值对数组。 请参阅以下示例:
const credits = { producer: 'John', director: 'Jane', assistant: 'Peter' };
const arr = Object.entries(credits);
console.log(arr);
/** 输出:
[ [ 'producer', 'John' ],
[ 'director', 'Jane' ],
[ 'assistant', 'Peter' ]
]
**/
25.Object.values()
这也是 ES8 中引入的一个新特性,它执行类似于 Object.entries() 的功能,但没有key部分:
const credits = { producer: 'John', director: 'Jane', assistant: 'Peter' };
const arr = Object.values(credits);
console.log(arr);
/** Output:
[ 'John', 'Jane', 'Peter' ]
**/
26.总结
如果还有短写技巧没有提到,请在评论区告诉我,谢谢!
作者: By Michael Wanyoike, Sam Deering 译者:前端很美 来源:sitepoint