美文网首页
ES6 简易示例

ES6 简易示例

作者: wyc0859 | 来源:发表于2022-03-04 15:40 被阅读0次

    Map对象

    Map对象 和 Objects 的区别
    Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
    一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。
    get 和 set方法

    const print = console.log
    var map1 = new Map()
    var keyString = 'a string'
    map1.set(keyString, "和键'a string'关联的值")
    const a1 = map1.get(keyString) // "和键'a string'关联的值"
    const a2 = map1.get('a string') // "和键'a string'关联的值"
    //print('a1-2:', a1, a2)
    

    Set对象

    Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
    Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。
    add方法

    let mySet = new Set()
    mySet.add(1) // Set(1) {1}
    mySet.add(5) // Set(2) {1, 5}
    mySet.add(5) // Set(2) {1, 5} 这里体现了值的唯一性
    mySet.add('some text') // Set(3) {1, 5, "some text"} 这里体现了类型的多样性
    
    var o = { a: 1, b: 2 }
    mySet.add(o) //Set(4) { 1, 5, 'some text', { a: 1, b: 2 } }
    //console.log(mySet)
    mySet.add({ a: 1, b: 2 }) // Set(5) { 1, 5, 'some text', { a: 1, b: 2 }, { a: 1, b: 2 } }
    // 这里体现了对象之间引用不同不恒等,即使值相同,Set 也能存储
    

    解构

    //数组解构
    let [a, b, c] = [1, 2, 3] // a = 1  b = 2  c = 3 
    let [e, , g] = [1, 2, 3] // e = 1  g = 3 
    
    //对象解构
    let { foo, bar } = { foo: 'aaa', bar: 'bbb' } // foo = 'aaa'  bar = 'bbb' 
    
    //注意下面不是逗号,是冒号
    let { x: y } = { x: 'x1' }   // y='x1'
    let { v: w } = { vv: 'v1' } // undefined
    // console.log(y) //打印x会报错  x1
    // console.log(w) //打印v会报错  undefined
    

    Proxy

    可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。
    一个Proxy对象由两个部分组成,构造函数生成实例需target目标对象 和 handler对象(声明代理target的指定行为)
    get 、 set、 construct、 has

    let target = {
      name: 'Tom',
      age: 20
    }
    let handler = {
      get: (target, key) => {
        console.log('get: ' + key)
        return target[key] // 不是target.key
      },
      set: (target, key, value) => {
        console.log('set: ' + key)
        target[key] = value
      }
    }
    let proxy = new Proxy(target, handler)
      //console.log(target, proxy) //2个相等 { name: 'Tom', age: 20 } { name: 'Tom', age: 20 }
      proxy.name // 实际执行 handler.get  //打印get: name
      proxy.age = 25 // 实际执行 handler.set  //打印set: age
    

    通过构造函数新建实例时其实是对目标对象进行了浅拷贝,因此目标对象与代理对象会互相影响


    Reflect

    可以用于获取目标对象的行为,它与 Object 类似,但是更易读,
    为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的
    get 、 set、 construct、 has

     //Reflect.get(target, name, receiver)
        let exam = {
          name: 'Tom',
          age: 24,
          get info() {
            return this.name + this.age
          }
        }
        const res = Reflect.get(exam, 'name')
        //console.log('res:', res) //res: Tom
    
        // 当target对象中存在name属性的getter方法,getter方法的this会绑定,参数3:obj
        let obj = {
          name: 'Jerry',
          age: 20
        }
        const r0 = Reflect.get(exam, 'info') // Tom24
        const r1 = Reflect.get(exam, 'info', obj) // Jerry20
        // 当 name 为不存在于 target 对象的属性时,返回 undefined
        const r2 = Reflect.get(exam, 'birth') // undefined
        //const r3 = Reflect.get(1, 'name') // 会报错,因为target不是对象 
    

    字符串

    includes和模板字符串

      const print = console.log 
      let string = 'apple,banana,orange'
      print(string.includes('banana')) // true  判断是否找到参数字符串
      print(string.startsWith('apple')) // true  判断参数字符串是否在原字符串的头部
      print(string.endsWith('apple')) // false  判断参数字符串是否在原字符串的尾部  
    

    这三个方法只返回布尔值,如果需要知道子串的位置,还是得用 indexOf

    模板字符串:字符串插入变量、表达式、调用函数

      let namea = 'Mike'
      let age = 27
      let info = `My Name is ${namea},I am ${age + 1} years old next year.` 
     
      function f() {
        return 'have fun!'
      }
      let string2 = `Game start,${f()}`
      console.log(string2) // Game start,have fun!
    

    对象object

    Object.assign() 与 Object.is()

    let age = { age: 15, city: 'beijing' }
    let names = { names: 'Amy', age: 18 } 
    let person2 = { ...age, ...names } //{ age: 18, city: 'beijing', names: 'Amy' } 同名的属性将被覆盖掉
    

    Object.assign(target, source_1, ···)
    用于将源对象的所有可枚举属性复制到目标对象中。

    let target = { a: 1 }
    let object2 = { b: 2 }
    let object3 = { c: 3 }
    Object.assign(target, object2, object3) // 第一个参数是目标对象,后面的参数是源对象
    console.log(target) //{ a: 1, b: 2, c: 3 }
    
    target = { ...target, ...object2, ...object3 }
    console.log(target) //{ a: 1, b: 2, c: 3 }
    
    //如果该函数只有一个参数,当参数为对象时,直接返回该对象;
    //当参数不是对象时,会先将参数转为对象然后返回。
    const objx = Object.assign(3)
    console.log(objx, typeof objx) // [Number: 3] object
    

    Object.is(value1, value2) 用来比较两个值是否严格相等,与(===)基本类似。

    Object.is('q', 'q') // true
    Object.is(1, 1) // true
    Object.is([1], [1]) // false
    Object.is({ q: 1 }, { q: 1 }) // false
    

    数组

    Array.of()、Array.from()

      console.log(Array.of(1, 2, 3, 4)) // [1, 2, 3, 4]
      console.log(Array.of(1, '2', true)) // [1, '2', true] // 参数值可为不同类型
      console.log(Array.of()) // [] // 参数为空时返回空数组
    

    Array.from() 将类数组对象或可迭代对象转化为数组。

    console.log(Array.from([1, 2])) // [1, 2]  参数为数组,返回与原数组一样的数组
    console.log(Array.from([1, , 3])) // [1, undefined, 3] 参数含空位
    
    //第2可选参数:map 函数、第3可选参数:thisArg(用于指定 map 函数执行时的 this 对象)
    let map = {
      do: (n) => {
        return n * 2
      }
    }
    let arrayLike = [3, 4, 5]
    const res = Array.from(
      arrayLike,
      function (n) {
        return this.do(n)
      },
      map
    )
    console.log(res) // [ 6, 8, 10 ]
    

    类"数组对象" 转数组
    一个类数组对象必须含有 length 属性,且元素属性名必须是数值或者可转换为数值的字符。

    let arr = Array.from({
      0: '1',
      1: '2',
      2: 3,
      length: 3
    })
    console.log(arr) // ['1', '2', 3]
    

    map转数组、set转数组、字符串转数组

    let map = new Map()
    map.set('key0', 'value0')
    map.set('key1', 'value1')
    console.log(Array.from(map)) // [['key0', 'value0'],['key1', 'value1']]
     
    let arr = [1, 2, 3]
    let set = new Set(arr)
    console.log(Array.from(set)) // [1, 2, 3]
     
    let str = 'abc'
    console.log(Array.from(str)) // ["a", "b", "c"]
    

    函数

    箭头函数有几个使用注意点。
    (1)箭头函数没有自己的this对象
    (2)不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误
    (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
    (4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数

    对于普通函数来说,内部的this指向函数运行时所在的对象

    var Person = {
      age: 18,
      sayHello: function (v) {
        //由于setTimeout异步,函数运行时所在的对象是setTimeout
        setTimeout(function () {
          console.log('this:', this) //this: Timeout {...}
          console.log('age:', this.age) //age: undefined
        }, 1000)
        return v * 2
      }
    }
    console.log('x:', Person.sayHello(2)) // x:4
    

    箭头函数则不一样,它没有自己的this对象,内部的this就是定义时上层作用域中的this

    var Person1 = {
      age: 18,
      sayHello: function (v) {
        //箭头函数上层作用域中的this,就是Person1对象
        setTimeout(() => {
          console.log('this:', this) // this: { age: 18, sayHello: [Function: sayHello] }
          console.log('age:', this.age) //age: 18
        }, 1000)
        return v * 2
      }
    }
    console.log('y:', Person1.sayHello(2)) // y:4
    

    箭头函数不可以当作构造函数

    function fun1(a, b) {
      console.log('new 函数,则函数是构造函数:', a + b)
    }
    const a1 = new fun1(1, 2)
    
    const fun2 = (a, b) => {
      console.log('new 箭头函数,会报错:', a + b)
    }
    //const a2 = new fun2(1, 2) //会报错 
    

    class类

    ES6 的类,完全可以看作构造函数的另一种写法。
    JS是用构造函数来充当”类“,TS类才是类似其他后端语言的类

    class Point {
      // ...
    }
    console.log(typeof Point) // "function"
    console.log(Point === Point.prototype.constructor) // true
    

    下面代码中的三个方法,其实都是定义在Point.prototype上面。

    class Point2 {
      constructor() {}
      toString() {}
      toValue() {}
    }
    // 等同于
    Point2.prototype = {
      constructor() {},
      toString() {},
      toValue() {}
    }
    

    封装与继承
    get和set

    class Example {
      constructor(a, b) {
        console.log('构造函数')
        this.a = a // 实例化时调用 set 方法
        this.b = b
      }
      // get 函数名 和 属性同名 才会触发
      get a() {
        console.log('get-a')
        //return this.a  //这样也会不断循环,
        return this._a
      }
      get b() {
        console.log('get-b')
        return this.b
      }
      set a(v) {
        console.log('set-a:', v)
        //this.a = a  //自身递归调用,不断循环,最终导致 RangeError
        this._a = v
      }
      set b(v) {
        console.log('set-b:', v)
      }
    }
    let exam = new Example(1, 2) //构造函数  set-a: 1   set-b: 2
    console.log(exam.a) //get-a  1
    
    
    class Father1 {
      constructor() {}
      get a() {
        return this._a
      }
      set a(v) {
        this._a = v
      }
    }
    class Child1 extends Father1 {
      constructor() {
        super()
      }
    }
    let test1 = new Child1()
    test1.a = 2
    console.log(test1.a) // 2
    

    模块

    ES6 的模块化分为导出(export) @与导入(import)两个模块
    模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等

    每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域
    每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取
    导出的函数声明与类声明必须要有名称(export default 命令另外考虑)
    export 命令可以出现在模块的任何位置,但必需处于模块顶层


    Generator 函数

    ES6新引入了Generator函数,可以通过yield关键字,把函数的执行流挂起,
    为改变执行流程提供了可能,从而为异步编程提供解决方案。 基本用法
    Generator 有两个区分于普通函数的部分:
    一是在 function 后面,函数名之前有个 *
    函数内部有 yield 表达式。
    其中 * 用来表示函数为 Generator 函数,yield 用来定义函数内部的状态。

    function* func() {
      console.log('one')
      yield '1'
      console.log('two')
      yield '2'
      console.log('three')
      return '3'
    }
    //调用 Generator 函数和调用普通函数一样,在函数名后面加上()即可,
    //但是 Generator 函数不会像普通函数一样立即执行,而是返回一个指向内部状态对象的指针
    const f = func() //不会立即执行,返回指针
    console.log(f.next()) //one  { value: '1', done: false }
    console.log(f.next()) //two  { value: '2', done: false }
    console.log(f.next()) //three  { value: '3', done: true }
    console.log(f.next()) // { value: undefined, done: true }
    console.log(f.next()) // { value: undefined, done: true }
    //如果执行第三步时,没有 return 语句的话,就直接返回 { value: undefined, done: true }
    

    相关文章

      网友评论

          本文标题:ES6 简易示例

          本文链接:https://www.haomeiwen.com/subject/ioqmrrtx.html