从今天开始你应该使用的 10 项现代 JavaScript
在Twitter上关注我,很高兴接受您对主题或改进的建议/Chris
您可能对 JavaScript 完全陌生,或者多年来只是偶尔使用过。但有一点是肯定的——JavaScript 已经发生了很大变化,有些功能您应该使用。如果您认真对待 JavaScript,本文将介绍我认为您应该每天使用的功能。
以下是视频版本:
资源
这些是我最喜欢的 ES6+ 资源:
-1- 扩展运算符
它表示为...对象或数组前的 ,其作用正如其名称所示,它将一个结构体转换为逗号分隔的列表。我们来演示一下:
展开数组
let firstHalf = [ 'one', 'two'];
let secondHalf = ['three', 'four', ...firstHalf];
这是一种简洁的写法。如果不这样写,则需要执行以下操作:
无阵列扩展
let firstHalf = [ 'one', 'two'];
let secondHalf = ['three', 'four'];
for(var i=0, i <firstHalf.length; i++ ) {
  secondHalf.push(firstHalf[i]);
}
这也可以用于对象上,作为合并其属性的一种方式:
传播对象
const hero = {
  name: 'Xena - Warrior Princess',
  realName: 'Lucy Lawless'
}
const heroWithSword = {
 ...hero,
 weapon: 'sword'
}
最困难的方法是循环遍历对象的所有属性:
无物体传播
let keys = Object.keys(hero);
let obj = {};
for(var i=0; i< keys.length; i++) {
   obj[keys[i]] = keys[props[i]];
}
公平地说,还有Object.assign(),看起来像这样:
const heroWithSword = Object.assign({}, hero, {weapon:"sword"})
但我仍然认为这是一个更容易阅读的内容:
const heroWithSword = {
 ...hero,
 weapon: 'sword'
}
-2- 剩余参数
剩余参数是指将剩余的参数收集到一个数组中。JavaScript 可以灵活地控制输入参数的数量。通常,会有一个arguments变量来收集这些参数。让我们来解释一下:
function add(first, second, ...remaining) {
  return first + second;
}
现在,上面只是总结了参数first和second。这意味着使用add(1,2)或调用它add(1,2,3, 4)会产生相同的结果。为了解决这个问题,我们可以输入:
function add(first, second, ...remaining) {
  return first + second + remaining.reduce((acc, curr) => acc + curr, 0);
}
以上意味着我们正在解决问题并使用所有输入参数。
如前所述,使用 rest 参数(即添加一个前缀...来收集剩余参数)是我们命名它们并更明确地表示我们想要使用它们的一种方式。arguments至少从 ES5 开始就已经存在,但我认为不太为人所知。
-3- 字符串插值
你见过这样的声明吗?
class Product {
 constructor(name, description, price) {
   this.name = name;
   this.description = description;
   this.price = price;
 }
 getDescription() {
   return " Full description \n" + 
   " name: " + this.name + 
   " description: " + this.description
 }
}
我当然是在说getDescription()方法,一个冗长、多行、难以阅读的语句。大多数编程语言都存在这种情况。有些语言也支持字符串插值,幸运的是,JavaScript 也不例外。我们可以将getDescription()方法改写成如下形式:
getDescription() {
   return `Full description \n: 
   name: ${this.name}
   description ${this.description}
   `;
 }
`所以,我们用双反引号来定义多行字符串。我们也用${}它来进行插值。希望你的世界现在好多了 :)
-4- 简写属性
你可能正在使用这个方法,但你却不知道。在 ES5 中,你需要这样写:
function createCoord(x, y) {
  return {
    x: x,
    y: y
  }
}
:在 ES6 及更高版本中,如果名称相同,则可以省略右侧的内容,如下所示:
function createCoord(x, y) {
  return {
    x,
    y
  }
}
看起来没那么混乱吧?
-5- 方法属性
这就是定义指向对象中方法的属性的方法。请考虑以下 ES5 示例:
const math = {
  add: function(a,b) { return a + b; },
  sub: function(a,b) { return a - b; }, 
  multiply: function(a,b) { return a * b; }
}
你实际上不需要add:ES6 及后续版本的全部代码。你可以像这样输入:
const math = {
  add(a,b) { return a + b; },
  sub(a,b) { return a - b; },
  multiply(a,b) { return a * b; }
}
-6- 解构
解构关乎您作为开发人员自身的精神健康。
对象解构
考虑以下代码:
function handle(req, res) {
 const name = req.body.name;
 const description = req.body.description;
 const url = req.url;
 log('url endpoint', url);
 // lots of logic happening
 dbService.createPerson( name, description )
}
上面的代码无论如何都不是完美的,但它确实代表了一种我们想要从不同层级的对象中挖掘数据的情况。你可能会问,这有什么问题?好吧,如果我不用声明所有这些变量,还能省去几次键盘敲击,会怎么样?你可以这样做:
function handle(req, res) {
 const { body: { name, description }, url }, = req;
 log('url endpoint', url);
 // lots of logic happening
 dbService.createPerson( name, description )
从上面您可以看到三行如何变成一行。
数组解构
这不仅限于对象,数组也可以。请考虑以下代码:
const array = [1,2,3,4,5,6];
const a = array[0];
const c = array[2];
这可以用一种更优雅的方式来实现,就像这样:
const array = [1,2,3,4,5,6];
const [a, ,c, ...remaining] = arr;
// remaining = [4,5,6]
我们可以直接通过上面的模式匹配从数组中取出值。如果我们想跳过一些输入的内容, ,,作为额外奖励,我还添加了一个 REST 语句来获取剩余的值。
参数匹配
我们也可以对函数及其参数执行此操作。当函数中有超过 2-3 个参数时,将所有参数收集到一个对象中已成为事实上的标准,因此你会得到如下所示的函数:
function doSomething(config) {
  if(config.a) { ... }
  if(config.b) { ... }
  if(config.c) { ... }
}
更好的方法是:
function doSomething({ a, b, c }) {
  if(a) { ... }
  if(b) { ... }
  if(c) { ... }
}
-7- 数组方法
ES6 带来了大量可用的数组方法,例如:
- find(),在列表中找到一项,否则为 null
- findIndex(),找到该项目的索引
- some(),谓词对于列表中的至少一个项目是否为真
- includes(),是列表的一部分
考虑以下代码来了解用法:
const array = [{ id: 1, checked: true }, { id: 2 }];
arr.find(item => item.id === 2) // { id: 2 }
arr.findIndex(item => item.id === 2) // 1
arr.some(item => item.checked) // true
const numberArray = [1,2,3,4];
numberArray.includes(2) // true
-8- Promises + Async/Await
如果你已经在这个圈子里待了一段时间,你可能会记得我们曾经只有回调函数,就像这样:
function doSomething(cb) {
  setTimeout(() =>  {
    cb('done')
  }, 3000)
}
doSomething((arg) => {
 console.log('done here', arg);
})
我们用它来处理一些异步操作,这些操作需要时间才能完成。之后,我们开发了人们开始使用的 Promise 库,并最终获得了语言的原生支持。现在我们可以做如下事情:
function doSomething() {
  return new Promise((resolve, reject) => {
    setTimeout(() =>  {
      resolve('done')
    }, 3000)
  })
}
doSomething().then(arg => {
 console.log('done here', arg);
})
我们甚至可以将整个体验串联起来,这样我们就可以进行如下调用:
getUser()
  .then(getOrderByUser)
  .then(getOrderItemsByOrder)
  .then(orderItems => {
    // do something with order items
  })
异步/等待
然后我们有了 async/await,生活变得更加精彩。考虑上面的例子,Promises 现在变成了这样:
async function getItems() {
  try {
    const user = await getUser();
    const order = await getOrderByUser(user);
    const items = await getOrderItemsByOrder(order);
    return items;
  } catch(err) {
    // handle error here, the suggestion to return something or rethrow
  }
}
getItems().then(items => {
  // do something with order items
})
我们得到了一个看起来同步的异步代码。:)
-9- 模块
几乎所有编程语言都支持模块的概念。模块可以将代码拆分成许多不同的文件,这些文件本身也是独立的单元,也就是所谓的模块。请考虑以下代码:
// math.js
export function add(a,b) { return a + b; }
export function sub(a,b) { return a - b; }
export default (a,b) => a * b;
// main.js
import mult, { add, sub } from './math';
mult(2, 4) // 8
add(1,1)   // 2
sub(1,2)   // -1
上面我们使用export关键字来表示这些构造函数add对于sub导入此模块的任何模块都是公开可用的。export default关键字是我们直接导入它时得到的。main.js我们导入默认函数时,会将其命名为 name mult,并且我们还特意挑选了方法add()和sub()
 -10- 箭头函数 + 词汇this
我在整篇文章中一直在使用箭头函数,它只是另一种函数符号。过去我们只能像这样编写函数:
function printArray(arr) {
 // do something
}
现在我们可以将其定义为:
const printArray = (arr) => {
 // do something
}
单行函数
我们还可以将函数定义为单行代码:
const add = (a,b) => a + b
这自动意味着我们执行操作并返回结果。我们也可以执行相同的操作并返回一个对象,语法如下:
const create = (a,b) = > ({ x: a, y: b })
词汇 this
 我们过去常常面临的问题是不知道它this是什么。考虑以下问题:
let array = [1,2,3];
function sum() {
  this.total = 0;
  arr.forEach(function(item) {
    this.total+= item;  // `this` is the inner functions `this`, BAD
  })
  return total;
} 
this在上述案例中, 内部的 点是错误的forEach。我们以前解决这个问题的方法是:
function sum() {
  this.total = 0;
  var self = this;
  arr.forEach(function(item) {
    self.total+= item;  // now we are using `self`, it solves it but feels hacky
  })
  return total;
} 
箭头函数解决了这个问题self,现在代码如下所示:
function sum() {
  this.total = 0;
  arr.forEach((item) => {
    this.total+= item;  // all is well `this` points to outer function
  })
  return total;
} 
获胜!
概括
关于 ES6 及其后续版本,我还有很多事情可以提及,但我只想向你展示我最喜欢的、我认为你今天应该采用的 ES6 :)
文章来源:https://dev.to/azure/modern-javascript-10-things-you-should-be-using-starting-today-1adm 后端开发教程 - Java、Spring Boot 实战 - msg200.com
            后端开发教程 - Java、Spring Boot 实战 - msg200.com