ES6重度学习 demo实例

let 与 const

// 并非真正的常量 
// const 的本质: const 定义的变量并非常量,并非不可变,
// 它定义了一个常量引用一个值。使用 const 定义的对象或者数组,其实是可变的。
// 下面的代码并不会报错:

// 创建常量对象
const car = {type:"Fiat", model:"500", color:"white"}; 
// 修改属性:
car.color = "red"; 
// 添加属性
car.owner = "Johnson";

// 创建常量数组
const cars = ["Saab", "Volvo", "BMW"]; 
// 修改元素
cars[0] = "Toyota"; 
// 添加元素
cars.push("Audi");

结构赋值

{ // 变量值交换 在之前我们得使用一个中间变量来存储
  let a = 1;
  let b = 2;
  [a, b] = [b, a];
  console.log(a, b); // 2 1
}

{
  function f(){ // 取出函数返回的两个值 例如: 商品单价 商品数量
    return [1, 2]
  }
  let a, b
  [a, b] = f()
  console.log(a, b) // 1 2
} 

{
  function f() { // 返回多个值时 选择性的接受某几个变量 忽略不想要的
    return [1, 2, 3, 4, 5]
  }
  let a, b, c;
  [a, , , b] = f()
  console.log(a, b); //1 4  
} 

{
  function f() {
    return [1, 2, 3, 4, 5]
  }
  let a, b, c;
  [a, , , ...b] = f()
  console.log(a, b); //1 [4, 5]
}

字符串的扩展

{
  let str = 'u{20bb7}abc'
  for (let i = 0; i < str.length; i++) {
    console.log(str[i]) // � � a b c
  }

  for(let code of str){
    console.log(code) // ? a b c
  }
}

对象的扩展

{
  // 新增API
  console.log('字符串', Object.is('abc', 'abc'), 'abc' === 'abc'); // 字符串 true true
  console.log('数组', Object.is([], []), [] === []); // 数组 false false
  console.log('拷贝', Object.assign({a: 'a'}, {b: 'b'})); // 浅拷贝  拷贝 {a: "a", b: "b"}
}

目前,ES7有一个提案,引入了跟Object.keys配套的Object.values和Object.entries。ES7兼容插件 import 'babel-polyfill';

symbol

{
  let a1 = Symbol.for('abc')
  let obj = {
    [a1]: '123',
    'abc': 345,
    'c': 456
  }
  console.log('obj', obj); // obj {abc: 345, c: 456, Symbol(abc): "123"}
  for(let i in obj){ //循环不到Symbol
    console.log(i);    // abc c
  } 
  console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(abc)]
  Object.getOwnPropertySymbols(obj).forEach(item => {
    console.log(obj[item]);    // 123
  })
  Reflect.ownKeys(obj).forEach(item => {
    console.log(item, obj[item]);    // abc 345   c 456   Symbol(abc) "123"
  })
}

set和map数据结构

set

 { // 数组去重
  let list = [2, 3, 5, 4, 5, '2', 2]
  let list2 = new Set(list)
  console.log(list2);   // Set(5) {2, 3, 5, 4, "2"}
 }
 
{ // 增删清查
 let arr = ['add', 'delete', 'clear', 'has']
 let list = new Set(arr)

 console.log('has', list.has('add'), list.entries()); 
 // has true SetIterator {"add", "delete", "clear", "has"}
 
 console.log('delete', list.delete('delete'), list.entries()); 
 // delete true SetIterator {"add", "clear", "has"}
 
 console.log('clear', list.clear('clear'), list.entries()); 
 // clear undefined SetIterator {}
 
 console.log('add', list.add('add'), list.entries()); 
 // add Set(1) {"add"} SetIterator {"add"}
}

WeakSet

  • WeakSet结构与Set类似,也是不重复的值的集合。但是,它与Set有两个区别。
    • 首先,WeakSet的成员只能是对象,而不能是其他类型的值。
    • 其次,WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特点意味着,无法引用WeakSet的成员,因此WeakSet是不可遍历的。

map

{ // 删清查
  let map = new Map([
    ['a', 123],
    ['b', 456]
  ])
  console.log('map', map); // map Map(2) {"a" => 123, "b" => 456}
  console.log('size', map.size); // size 2  
  console.log('delete', map.delete('a'), map); // delete true Map(1) {"b" => 456}
  console.log('clear', map.clear(), map); // clear undefined Map(0) {}  
}

WeakMap

{
  let weakmap = new WeakMap()

  let o = {}
  weakmap.set(o, 123)
  console.log(weakmap); // WeakMap {{…} => 123}__proto__: WeakMap[[Entries]]: Array(0)length: 0
}

map-set与数组和对象的比较

Proxy 和 Reflect

{ // 代理校验
  function validator(target, validator) {
    return new Proxy(target, {
      _validator: validator,
      set(target, key, value, proxy) {
        if (target.hasOwnProperty(key)) {
          let va = this._validator[key]
          if (!!va(value)) {
            return Reflect.set(target, key, value, proxy)
          } else {
            throw Error(`不能设置${key}到${value}`)
          }
        } else {
          throw Error(`${key}不存在`)
        }
      }
    })
  }

  const personValidators = {
    name(val) {
      return typeof val === 'string'
    },
    age(val) {
      return typeof val === 'number' && val > 18
    }
  }

  class Person {
    constructor(name, age) {
      this.name = name
      this.age = age
      return validator(this, personValidators)
    }
  }

  const person = new Person('lilei', 30)
  console.info(person)
  // person.name = 48 //报错: 不能设置name到48
  // person.sex = '男' // sex不存在
  person.name = 'han meimei'
  console.info(person) // Proxy {name: "lilei", age: 30}
}

class

{
  // 基本定义和生成实例
  class Parent {
    constructor(name = 'zhangsan') {
      this.name = name
    }
  }
  let v_parent = new Parent('v')
  console.log('构造函数和实例', v_parent) // 构造函数和实例 Parent {name: "v"}
}

{
  // 继承
  class Parent {
    constructor(name = 'lisi') {
      this.name = name
    }
  }
  class Child extends Parent {
    constructor(name = 'child') {
      // this.type = 'child' // 报错
      super(name) // 子类想父类传递参数
      this.type = 'child'
    }
  }

  console.log('继承', new Child) // 继承 Child {name: "child", type: "child"}
}

{
  // getter, setter
  class Parent {
    constructor(name = 'wanger') {
      this.name = name
    }
    get longName() {
      return 'mk' + this.name
    }
    set longName(value) {
      this.name = value
    }

  }
  let v = new Parent()
  console.log('getter', v.longName) // getter mkwanger
  v.longName = 'hello'
  console.log('setter', v.longName) // setter mkhello
}

{
  // 静态方法
  class Parent {
    constructor(name = 'zhaowu') {
      this.name = name
    }
    static tell() {
      console.log('tell')
    }
  }

  Parent.tell() // tell
}

{
  // 静态属性
  class Parent{
    constructor(name = 'sunshangxiang'){
      this.name = name
    }
    static tell (){
      console.log('tell')
    }
  }
  Parent.type = 'test'
  console.log('静态属性', Parent.type) // 静态属性 test
}

promise对象

{
  // 所有图片加载完再添加到页面
  function loadImg(src) {
    return new Promise(function (resolve, reject) {
      let img = document.createElement('img')
      img.src = src
      img.onload = function () {
        resolve(img)
      }
      img.onerror = function (err) {
        reject(err)
      }
    })
  }

  function showImgs(imgs) {
    imgs.forEach(img => {
      document.body.appendChild(img)
    });
  }
  Promise.all([ // 所有图片加载完后执行
    loadImg('http://pic37.nipic.com/20140113/8800276_184927469000_2.png'),
    loadImg('http://pic37.nipic.com/20140113/8800276_184927469000_2.png'),
    loadImg('http://pic37.nipic.com/20140113/8800276_184927469000_2.png')
  ]).then(showImgs)
}
{
  // 多个图片服务器, 加载最快的一个
  // 有一个图片加载完成就添加到页面
  function loadImg(src) {
    return new Promise((resolve, reject) => {
      let img = document.createElement('img')
      img.src = src
      img.onload = function () {
        resolve(img)
      }
      img.onerror = function () {
        reject(err)
      }
    })
  }
  function showImg(img){
    document.body.appendChild(img)
  }

  Promise.race([ // 谁先请求到 就显示谁
    loadImg('http://img2.imgtn.bdimg.com/it/u=234634259,4236876085&fm=26&gp=0.jpg'),
    loadImg('http://img4.imgtn.bdimg.com/it/u=2153937626,1074119156&fm=26&gp=0.jpg'),
    loadImg('http://img1.imgtn.bdimg.com/it/u=1483033257,4287748004&fm=26&gp=0.jpg')
  ]).then(showImg)
}

修饰器

{
  // 函数属性为只读

  /**
   * 修饰器基本用法
   * 1 修饰器是一个函数
   * 2 修改的行为
   * 3 修改类的行为
   */
  let readonly = function (target, name, descriptor) {
    descriptor.writable = false
    return descriptor
  }
  
  class Test {
    @readonly
    time() {
      return '2019-0526'
    }
  }
  let test = new Test()

  test.time = function () {
    console.log('rest time')
  }
  console.log(test.time()) 
  // cannot assign to read only property 'time' of object '#<Test>'
}

第三方库修饰器的js库: core-decorators

原文地址:https://www.cnblogs.com/izhaong/p/12154297.html