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
}
posted @ 2020-07-29 00:06  c-137Summer  阅读(292)  评论(0编辑  收藏