16 个有用的 TypeScript 和 JavaScript 小技巧

14,905

前言

JavaScript 和 TypeScript 中有许多常用代码的简写方式可以共享,使用简写方式,可以有效的减少我们的代码量。

在本文中我们来回顾下常见的16种 TypeScript 的简写方式,并来说说这些简写方式的使用场景。

简写方式

在编写干净且可扩张的代码时,使用简写方式并不总是正确的决定.简洁的代码更容易阅读和更新,我们的代码必须清晰易读,并能向其他的开发人员传达清晰的含义,这一点很重要。

JavaScript 中的简写方式大部分都能在 TypeScript 中适用,但是除了那么一部分以外。

1.三元运算符

三元运算符是 JavaSacript 和 TypeScript 中最流行的简写之一。它取代了传统的的 if-else 写法, 语法如下:

[condition] ? [true result] : [false result]

示例:

// Longhand

const mark = 80

if (mark >= 65) {
  return "Pass"
} else {
  return "Fail"
}

// Shorthand
const mark = 80

return mark >= 65 ? "Pass" : "Fail"

2. 短路运算符

另外一种替换 if-else 的方法是短路运算。当预期值为假时,此简写方式就会为表达式分配默认值。

示例:

// Longhand
let str = ''
let finalStr

if (str !== null && str !== undefined && str != '') {
  finalStr = str
} else {
  finalStr = 'default string'
}

// Shorthand
let str = ''
let finalStr = str || 'default string' // 'default string

3. Null值判断

null 值合并运算符 ?? 类型于短路运算符,因为它也是为变量分配默认值,但是 空值运算符仅在预期值为空值时使用默认值

换句话说就是 如果预期值是 false 但不是null,将不会使用默认值

示例:

// Example 1
// Longhand
let str = ''
let finalStr

if (str !== null && str !== undefined) {
  finalStr = 'default string'
} else {
  finalStr = str
}
// Shorthand
let str = ''
let finaStr = str ?? 'default string' // ''

// Example 2
// Longhand
let num = null
let actualNum

if (num !== null && num !== undefined) {
  actualNum = num
} else {
  actualNum = 0
}
// Shorthand
let num = null
let actualNum = num ?? 0 // 0

4. 模板字符串

使用 JavaScript 的ES6特性,我们可以使用模板字符串来连接多个变量,而不用使用 +, 要使用模板字符串,我们可以使用 ``${}

示例:

const name = 'Iby'
const hobby = 'to read'

// Longhand
const fullStr = name + ' loves ' + hobby // 'Iby loves to read'

// Shorthand
const fullStr = `${name} loves ${hobby}`

我们还可以使用模板字符串来构建多行字符串,而无需使用 \n

示例:

// Shorthand
const name = 'Iby'
const hobby = 'to read'
const fullStr = `${name} loves ${hobby}.
She also loves to write!` 

5. 对象属性的简洁写法

在JavaScript 和 TypeScript 中,我们可以使用对象字面量中申明变量的简写形式将属性分配给对象

这里要说明的是命名变量要和赋值的变量名称一致

示例:

// Longhand
const obj = {
  x: 1,
  y: 2,
  z: 3
}

// Shorthand
const x = 8
const y = 10
const obj = { x, y }

6. 可选链

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效.如果访问的属性不存在,可选链中的值为 undefined

示例:

const obj = {
  x: {
    y: 1,
    z: 2
  },
  others: [
    'test',
    'tested'
  ] 
}

// Longhand
if (obj.hasProperty('others') && others.length >= 2) {
  console.log('2nd value in others: ', obj.others[1])
}

// Shorthand
console.log('2nd value in others: ', obj.others?.[1]) // 'tested'
console.log('3rd value in others: ', obj.others?.[2]) // undefined

7. 对象解构

获取对象的属性,除了点表示法以外,还有一种方法就是使用对象解构

示例:

const obj = {
  x: {
    y: 1,
    z: 2
  },
  others: [
    'test',
    'tested'
  ] 
}

// Longhand
if (obj.hasProperty('others') && others.length >= 2) {
  console.log('2nd value in others: ', obj.others[1])
}

// Shorthand
console.log('2nd value in others: ', obj.others?.[1]) // 'tested'
console.log('3rd value in others: ', obj.others?.[2]) // undefined

这里我们还可以重命名从对象中解构的变量。

示例:

const obj = {x: 1, y: 2}
const {x: myVar} = object

console.log('My renamed variable: ', myVar) // My renamed variable: 1

8. 扩展操作符

扩展操作符 ... 用于访问数组和对象的内容

示例:

// Longhand
const arr = [1, 2, 3]
const biggerArr = [4,5,6].concat(arr)

const smallObj = {x: 1}
const otherObj = object.assign(smallObj, {y: 2})

// Shorthand
const arr = [1, 2, 3]
const biggerArr = [...arr, 4, 5, 6]

const smallObj = {x: 1}
const otherObj = {...smallObj, y: 2}

9. for 循环

我们之前使用 for 循环的方式如下:

for (let i = 0; i < x; i++) { … }

我们通过引用迭代器的数组长度来使用循环语法遍历数组

这里有三种 不同的 for 循环的语法来遍历数组对象

  • for...of
  • for... in
  • Array.forEach

这里使用Array.forEach 要注意的是回调函数中可以有三个参数

  • 正在迭代的数组元素
  • 元素的索引
  • 数组本身

示例:

// Longhand
const arr = ['Yes', 'No', 'Maybe']

for (let i = 0; i < arr.length; i++) {
  console.log('Here is item: ', arr[i])
}

// Shorthand
for (let str of arr) {
  console.log('Here is item: ', str)
}

arr.forEach((str) => {
  console.log('Here is item: ', str)
})

for (let index in arr) {
  console.log(`Item at index ${index} is ${arr[index]}`)
}

// For object literals
const obj = {a: 1, b: 2, c: 3}

for (let key in obj) {
  console.log(`Value at key ${key} is ${obj[key]}`)
}

10. Array.indexOf

我们可以使用这个方法来查找数组是否存在某个元素,如果数组存在该元素,则返会该元素在数组中的索引位置,如果不存在则返回 -1

这里我们可以使用 if...else 来根据返回的索引判断元素是否存在。当然,我们也可以使用前面说过的三元表达式来判断

示例:

// Longhand
if (realNumIndex > -1) {
  console.log(realNum, ' exists!')
} else if (realNumIndex === -1) {
  console.log(realNum, ' does not exist!')
}

if (noneNumIndex > -1) {
  console.log(fakeNum, ' exists!')
} else if (noneNumIndex === -1) {
  console.log(fakeNum, ' does not exist!')
}

// Shorthand
console.log(realNum + (~realNumIndex ? ' exists!' : ' does not exist!')
console.log(fakeNum + (~noneNumIndex ? ' exists!' : ' does not exist!')

11. 使用 !! 将值转换为boolean

在JavaScript中,我们可以使用 !! 将如何类型的变量转换为布尔值。

!![variable]

示例:

// Longhand
const simpleInt = 3
const intAsBool = Boolean(simpleInt)

// Shorthand
const simpleInt = 3
const intAsBool = !!simpleInt

12. 箭头函数

JavaScript 中的函数可以使用箭头函数语法书写,省去 function 关键字,箭头函数类似与其他语言中的 lambda 函数

示例:

// Longhand
function printStr(str) {
  console.log('This is a string: ', str)
}
printStr('Girl!')

// Shorthand
const printStr = (str) => {
  console.log('This is a string: ', str)
}
printStr('Girl!')

// Shorthand TypeScript (specifying variable type)
const printStr = (str: string) => {
  console.log('This is a string: ', str)
}
printStr('Girl!')

13. 箭头函数中隐式返回

通常在函数中我们使用 return 关键字从函数返回值,但是在箭头函数中我们可以使用简写方式

但如果是多行的表达式时,就必须使用 {}

示例:

function printStr(str) {
  console.log('This is a string: ', str)
}
printStr('Girl!')

// Shorthand
const printStr = (str) => {
  console.log('This is a string: ', str)
}
printStr('Girl!')

// Shorthand TypeScript (specifying variable type)
const printStr = (str: string) => {
  console.log('This is a string: ', str)
}
printStr('Girl!')

14. ~~操作符

在 JavaScript 中,我们通常使用内置的 Math 对象来访问内置函数,这里我们可以使用一些简写的方式,在不引用 Math对象的情况下访问内置函数,如使用 ~~ 操作符得到和 Math.floor() 一样的值

示例:

// Longhand
const num = 4.5
const floorNum = Math.floor(num) // 4

// Shorthand
const num = 4.5
const floorNum = ~~num // 4

15. 指数幂

指数幂也有简写方式

示例:

// Longhand
const num = Math.pow(3, 4) // 81

// Shorthand
const num = 3 ** 4 // 8

16. TypeScript 构造函数

通过 TypeScript 中的构造函数创建一个类,并为这个类赋值的简写方式,这个简写方式是TypeScript 独有的,在 JavaScript 类定义中不可用

示例:

// Longhand
class Person {
  private name: string
  public age: int
  protected hobbies: string[]

  constructor(name: string, age: int, hobbies: string[]) {
    this.name = name
    this.age = age
    this.hobbies = hobbies
  }
}

// Shorthand
class Person {
  constructor(
    private name: string,
    public age: int,
    protected hobbies: string[]
  ) {}
}