19+ 个 JavaScript 快速编程技巧 — SitePoint

19+ 个 JavaScript 快速编程技巧 — SitePoint

本文转载自:众成翻译
译者:myvin
链接:http://www.zcfy.cc/article/3519
原文:https://www.sitepoint.com/shorthand-javascript-techniques/

这确实是一篇针对于基于 JavaScript 语言编程的开发者必读的文章。在过去几年我学习 JavaScript 的时候,我写下了这篇文章,并将其作为 JavaScript 快速编程技巧的一个重要参考。为了有助于理解,针对常规写法我也给出了相关的编程观点。

2017 年 6 月 14 日:这篇文章更新了一些基于 ES6 的速记写法。如果你想进一步了解 ES6 中有哪些新增的变化,可以注册 SitePoint Premium 并查看我们录制的视频A Look into ES6

1. 三元操作符

如果你想只用一行代码写出一个 if..else 表达式,那么这是一个很好的节省代码的方式。

常规写法:

const x = 20;
let answer;
if (x > 10) {
    answer = 'is greater';
} else {
    answer = 'is lesser';
}

速记法:

`const answer = x > 10 ? 'is greater' : 'is lesser';`

你也可以像这样嵌套 if 表达式:

`const big = x > 10 ? " greater 10" : x`

2. 短路求值速记法

当需要给另一个变量分配一个变量时,你可能需要确保变量不是 null、undefined 或者不为空。你可以写一个有多个 if 表达式的语句,你也可以使用短路求值。

常规写法:

if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
     let variable2 = variable1;
}

速记法:

`const variable2 = variable1  || 'new';`

你不相信这样可以 work?那就自己测试下吧(把下面的代码复制粘贴到 es6console):

let variable1;
let variable2 = variable1  || '';
console.log(variable2 === ''); // prints true

variable1 = 'foo';
variable2 = variable1  || '';
console.log(variable2); // prints foo

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 循环速记法

如果你只想跑原生 JavaScript,不想依赖如 JQuery 或 lodash 这样的外部库,那这个小技巧会非常有用。

常规写法:

`for (let i = 0; i < allImgs.length; i++)`

速记法:

`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

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. 十进制基数指数

你可能随处可见这种写法。这是一种比较 fancy 的写法,省去了后面的一堆零。举个栗子,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;

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 值在箭头函数和常规写法的函数里是完全不同的,所以那两个例子并不是严格等价的。查看 this article on arrow function syntax获取更多细节。

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, 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 代码使用起来更高效、更有趣。它可以用来替换某些数组函数。展开运算符写起来很简单,就是三个点。

常规写法:

// 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 }

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

这个函数完美的实现了所需的功能。但是,请考虑一个场景:你有许多表单需要验证,并且不同的域有不同的验证规则。那创建一个在运行时被配置的通用验证函数岂不是更好?

速记法:

// 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

现在创建了一个可以在所有的表单里重用的验证函数,而不必为每个表单单独写一个特定的验证函数。

19. 双位取反运算符速记法

逐位运算符是你在刚学习 JavaScript 时会学到的一个特性,但是如果你不处理二进制的话,基本上是从来都不会用上的。

但是,双位运算符有一个非常实用的使用场景:可以用来代替 Math.floor。双位取反运算符的优势在于它执行相同操作的速度更快。你可以在这里查看更多关于位运算符的知识。

常规写法:

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

速记法:

`~~4.9 === 4  //true`

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容

  • FreeCodeCamp - Basic JavaScript 写在前面: 我曾经在进谷前刷过这一套题,不过当时只...
    付林恒阅读 16,417评论 5 28
  • 原文: https://github.com/ecomfe/spec/blob/master/javascript...
    zock阅读 3,370评论 2 36
  • 三,字符串扩展 3.1 Unicode表示法 ES6 做出了改进,只要将码点放入大括号,就能正确解读该字符。有了这...
    eastbaby阅读 1,506评论 0 8
  • 记得关注新浪博客的时候是2010年,那时只是为了浏览一些财经文章,主要看一些股票分析。简单的注册了博客,关注了数十...
    一片光阅读 173评论 0 0
  • 突然发现岁月不仅在父母的身上留下了深深地纹路,原来在自己的脸上也留下了匆匆走过的痕迹,突然觉得自己不再年幼,细...
    木兮_fa82阅读 262评论 3 5