ES 新特性與 TypeScript 筆記


ES新特性

JS 中的作用域有幾種

全局作用域
函數作用域
塊級作用域ECAMAScript2015(ES6)

ECAMAScript2015

let const

解構賦值

// 數組解構
const arr = [1,2,3]  
const [a,b,c] = arr 
// 對象解構
const obj = {name:’zhangsan’, age: 20}
const { name:objName } = obj // 重命名

模板字符串

`${objName}\n`
// 帶標簽的模板字符串
const str = console.log`hello world` // ['hello world']

字符串的擴展方法

const message = `Error: foo is not defined.`
console.log(message.startWith('Error')) // true
console.log(message.endWith('.')) // true
console.log(message.includes('foo')) // true

參數默認值

function foo(enable=true) {
  console.log(enable)
}
foo() // true

剩余參數

function foo (...args) { // 只能出現在形參的最后一位,只能使用一次
  console.log(args)
}
foo([1,2,3])

spread 展開數組

const arr = ['a','b','c']
console.log(...arr)

箭頭函數

function inc (number) {
  return number + 1
}
const inc = (m,n)=> m+n
console.log(inc(1,3)) // 3

// 不會改變this的指向
const person = {
  name: 'tom',
  say: ()=>{
    console.log(this.name)
  },
  sayAsync: function() {
    setTimeout(()=>{
      console.log(this.name)
    })
  }
}

person.say() // undefined 

對象字面量的增強

const obj = {
  name:'zhangsan',
  foo(){ // 等價於:function聲明

  },
  [name]:100 // 變量名也可動態
}

對象擴展方法

Object.assign(obj, target) // 后面對象覆蓋前面的
Object.is(+0, -0) // true
Object.is(NaN, NaN) // true
// Object.definedProporty() 只能監聽到對象的讀寫 對數組的監聽是重寫方法$set

Proxy

// 能監視到更多對象操作 或對對象方法的調用 更好的支持數組監聽 是以非侵入方式監管對象的讀寫

const person = {
  name:'aaa',
  age: 90
}

const personProxy = new Proxy(person, {
  get(target, property) {
    return property in target ? target[property] : 'default'
    console.log(target, property)
    // return 10
  },
  set(target, property, value) {
    if(property==='age') {
      if(!Number.isInteger(value)) {
        throw new TypeError(`${value} is not an int`)
      }
    }
    target[property] = value
    console.log(target, property, value)
  }
})

personProxy.age = 25
personProxy.gender = true

// console.log(personProxy.name) // 10
// console.log(personProxy.name) // aaa


const list = []
const listProxy = new Proxy(list, {
  set (target, property, value) {
    console.log('set', property, value)
    target[property] = value
    return true
  }
})

listProxy.push(100)

Reflect

// 統一的對象操作API 內部封裝了一系列對對象的底層操作 成員方法就是Proxy對象中對應的方法

const obj = {
  name:'aaa',
  age: 90
}

// console.log('name' in obj)
// console.log(delete obj.age)
// console.log(Object.keys(obj))

console.log(Reflect.has(obj, 'name'))
console.log(Reflect.deleteProperty(obj, 'age'))
console.log(Reflect.ownKeys(obj))

Promise

class 類

function Person(name) {
  this.name = name
}

class Person {
  constructor(name) {
    this.name = name
  }
  say() {
    console.log(this.name)
  } 
  static create(name) { // 靜態成員 static
    return new Person(name)
  }
}

const n = new Person('SUMMER')
const tom = Person.create('tom') 
tom.say()

// 類的繼承
class Student extends Person { // 繼承person所有參數
  constructor(name, number) {
    super(name) // 調用它就是調用父類的所有方法
    this.number = number
  }
  hello() {
    super.say()
    console.log(this.number)
  }
}

const s = new Student('tom', 100)
console.log(s)

Set 數據結構 集合

const s = new Set()
s.add(1).add(2).add(3)

s.forEacg(i=>console.log(i))
s.size
s.has(100) // false
s.delete(3)
s.clear()

// 數組去重 new Set
const arr = [1,2,1,3,4,5]
const result = Array.from(new Set(arr))
const result = [...new Set(arr)]

Map

// 可以把Object作為鍵 對象只能用字符串做鍵

const obj = {}
obj[true] = 'value'
obj[123] = 'value'
obj[{a:1}] = 'value'
const m = new Map()
const tom = {name: 'tom'}
m.set(tom, 90)
console.log(m)
m.has()
m.delete()
m.clear()
m.forEach((value,key)=>{
  console.log(key)
})

Symbol // 表示一個獨一無二的值

// 通過Symbol創建的值都是獨一無二的
// 可以作為對象的屬性名
// 創建私有成員

Iterator

// for of 循環 可以遍歷所有的有Iterator的
const arr = [1,2,3]
for(const item of arr) {
  console.log(item)
}

// 實現可迭代接口 Iterable
const obj = {
  store: ['foo','bar','baz'],
  [Symbol.iterator]: function () {
    let index = 0
    const self = this
    return {
      next: function () {
        const result = {
          value: self.store[index],
          done: index >= self.store.length
        }
        index ++
        return result
      }
    }
  }
}

for (const item of obj) {
  console.log('循環體')
}

// 作用:對外提供統一遍歷接口 適合於任何數據結構

生成器 generator 異步編程解決方案

function * foo () {
  console.log('111')
  yield 100
  console.log('222')
  yield 200
  console.log('333')
  yield 300
}

const res = foo()
console.log(res) // 打印生成器對象
console.log(res.next()) // 實現了迭代器接口


const generator = foo()
console.log(generator.next()) // 遇到yield暫停 111 {value: 100, done: false}
console.log(generator.next()) // 遇到yield暫停 222 {value: 200, done: false}
console.log(generator.next()) // 遇到yield暫停 333 {value: 300, done: false}
console.log(generator.next()) // 遇到yield暫停  {value: undefined, done: true}

生成器應用

案例:使用generator函數實現iterator方法

const todos = {
  life: ['吃飯','睡覺'],
  learn: ['學習'],
  work: ['摸魚'],
  [Symbol.iterator]: function * () {
    const all = [...this.life, ...this.learn, ...this.work]
    for (const item of all) {
      yield item
    }
  }
}
for (const item of todos) {
  console.log(item)
}

ECAMAScript2016

includes

[1,2,3].includes(2) // true
[1,2,3].includes(NaN) // false

指數運算符

console.log(Math.pow(2,3)) // 以前指數運算
console.log(2 ** 10) // 現在指數運算

ECAMAScript2017

Object.values、Object.entries

Object.values(obj)
Object.entries(obj)
new Map(Object.entries(obj))

getOwnPropertyDescriptors

const p1 = {
  firstName: 'lei',
  lastName: 'wang',
  get fullName() {
    return this.firstName+' '+this.lastName
  }
}

console.log(p1.fullName)

const p2 = Object.assign({}, p1) // 復制的時候值當做普通屬性復制

p2.firstName = 'zhangsan'
console.log(p2) // 打印的還是p1內容

const desc = Object.getOwnPropertyDescriptors(p1)
console.log(desc)
const p2 = Object.definedPropories({}, desc)
p2.firstName = 'zhangsan'
console.log(p2.fullName)

padStart/padEnd 補齊

const books = {
  html: 3,
  css: 10,
  javascript: 120
}

for(const [name, count] of Object.entries(books)) {
  console.log(`${name.padEnd(16, '-')}|${count.toString().padStart(3, '0')}`)
}

函數參數中添加尾逗號

function foo (
  bar, baz,) {
}

TypeScript

TypeScript解決JavaScript類型系統的問題
編程語言從類型安全角度分為強類型與弱類型
從類型檢查角度分為靜態類型與動態類型
強類型不允許任意類型的隱式類型轉換 // 編譯階段就不允許
靜態類型一個變量聲明是就是確定的,並且不允許修改

強類型優點

  1. 錯誤更早暴露
  1. 代碼更智能,編碼更准確
  2. 重構更牢靠
  3. 減少不必要的類型判斷

類型注解

const hello = (name: string) => {
  console.log(name)
}

console.log('jdsodj')

基本類型

const a: string = ''
const b: number = 1
const c: boolean = true
const d: void = undefined
const e: null = null
const f: undefined = undefined

枚舉類型

enum postStatus {
    startus0 = 0, // 如果是數字還會自增
    startus1,
    startus2
}

// postStatus[0]
// postStatus.startus0

函數類型 FunctionType

const s = (name: string, age?: number) => {
  console.log(name+age)
}

s('hahha')

隱式類型推斷

let age = 10 // 推斷為number
let foo // 推斷為any 

類型斷言 as <>

const nums = [1,2,3]
const res = nums.find(i=>i>0)
const num = res as number
const num2 = <number>res  // <> jsx下沖突 建議用as

接口 interface 約束對象的結構

interface Post {
    title: string
    num: number
    subtitle?: string // 可選成員
    readonly summary: string // 只讀成員
}

function printPost(post: Post) {
  console.log(post.title)
  console.log(post.num)
}

printPost({
  title: 'ahhha',
  num: 1000,
  summary: 'ok'
})

類 - 描述一類事物的具體特征 ts增強了class的語法

class Person {
  public name: string // 默認public
  age: number
  private weight: number  // 私有屬性
  protected readonly gender: boolean  // protected只允許在子類中訪問的成員 readonly只讀

  constructor (name: string, age: number) { // 構造函數也可設置為private protected
    this.name = name
    this.age = age
  }

  say(msg: string):void {
    console.log(`${this.name}: ${this.age}${msg}`)
  }
}

class Student extends Person {
  constructor(name: string, age: number) {
    super(name, age)
    console.log(this.gender)
  }
}

implements 擴充

interface Eat {
  eat (food: string): void
}
interface Run {
  run (distance: number): void
}

class Dog implements Eat, Run {
  eat (food: string):void {
    console.log(food)
  }
 run (distance: number):void {
    console.log(distance)
  }
}

class Pig implements Eat, Run {
  eat (food: string):void {
    console.log(food)
  }
 run (distance: number):void {
    console.log(distance)
  }
}

抽象類 -只能被繼承

abstract class Animal {
  eat(food: string):void {
    console.log(food)
  }
  abstract run (distance: number): void
}

泛型 定義的時候不指定類型 調用的時候再確定類型

function createArr<T> (length: number, value: T): T[] {
  const arr = Array<T>(length).fill(value)
  return arr
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM