ES6 手写

83 阅读2分钟

对象可以使用的for of

for...of 在可迭代对象上创建一个迭代循环,其中可迭代对象的要求为对象必须实现@@iterator方法 developer.mozilla.org/zh-CN/docs/… 自己实现的kitterable对象中必须有一个[Symbol.iterator]属性,且是一个无参数的函数,返回一个对象(A), 对象(A)中有一个next属性,是一个返回带有done(boolean)和value属性的对象的函数

    let iterableobj = {
        i: 0,
        [Symbol.iterator]: () => {
            return {
                next: () => {
                    if(iterableobj.i < 3){
                      iterableobj.i++
                        return {
                            value: iterableobj.i,
                            done: false
                        }
                    } else {
                        return {
                            value: undefined,
                            done: true
                        }
                    }
                }
            }
        }
    }

试验一下

for (var value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

for...in 遍历对象

for in 遍历对象时,会把原型链上的可枚举属性也遍历一下

 let obj = {a: 1, b: 2}
     Object.prototype.c = 3
     for(let key in obj){
       console.log(key)
     }
     
     // a
     // b
     // c

但是我们可以加一个Obj.hasOwnProperty()来判断一下是不是对象自身属性中具有指定的属性

 let obj = {a: 1, b: 2}
     Object.prototype.c = 3
     for(let key in obj){
       if(obj.hasOwnProperty(key)){
        console.log(key)
       }
     }
     
     // a
     // b

Object.keys()

Object.keys()返回一个给定对象的⾃身可枚举属性组成的数组

 Object.prototype.c = 3
     let obj = {a: 1, b: 2}
     let keys = function (obj){
       let arr = []
        for(let key in obj){
          if(obj.hasOwnProperty(key)){
            arr.push(key)
          }
        }
        return arr
     }
    
    // a
    // b

Object.values()

Object.values返回⼀个给定对象⾃身的所有可枚举属性值的数组

Object.prototype.c = 3
     let obj = {a: 1, b: 2}
     let values = function (obj){
       let arr = []
        for(let key in obj){
          if(obj.hasOwnProperty(key)){
            arr.push(obj[key])
          }
        }
        return arr
     }
     
     // 1
     // 2

Object.entries

Object.entries返回⼀个给定对象⾃身可枚举属性的键值对数组

 Object.prototype.c = 3
     let obj = {a: 1, b: 2}
     let entries = function (obj){
       let arr = []
        for(let key in obj){
          if(obj.hasOwnProperty(key)){
            arr.push([key, obj[key]])
          }
        }
        return arr
     }
     
     // [[a: 1], [b, 2]]

Object.getOwnPropertyNames()

同Object.keys()

Object.assign

浅拷贝

function shallowClone(source) {
    const target = {};
    for (const i in source) {
        if (source.hasOwnProperty(i)) {
            target[i] = source[i];
        }
    }
    return target;
}

Array.flat

按照指定深度将数组扁平化

function flat(arr, num = 1){
      console.log(num)
      if(num === 0) return arr
      return arr.reduce((res, val) => {
        if(Array.isArray(val)){
          res = res.concat(flat(val, num-1))
        } else {
          res = res.concat(val)
        }
        return res
      }, [])
    }

Array.includes

来判断⼀个数是否包含⼀个指定的值.

类数组转为真数组

  1. [...arguments]
  2. Array.form
  3. Array.prototype.slice.call(arguments)

继承

原型链继承

    function Parent(name){
        this.name = name
      }
      Parent.prototype.getName = function(){
        console.log(this.name)
      }
      let parent = new Parent('parent')
      function Child(){}
      Child.prototype = parent
      let child = new Child('child')
      child.constructor = Child
      child.getName()

缺点:
1.无法传参
2. 当属性为引用类型时,一个实例修改会对所有实例产生影响

构造函数继承

    function Parent(name, food){
        this.name = name
        this.eat = {food}
      }
      function Child(name, food){
        Parent.call(this, name, food)
      }
      let child1 = new Child('aa', 'apple')
      let child2 = new Child('bb', 'orange')

缺点: 属性或者方法只能定义在构造函数内部,每次创建实例的时候,都需要创建一遍方法

组合继承

    function Parent(name, food){
        this.name = name
        this.eat = {food}
      }
      Parent.prototype.actions = function(){
        console.log(this.eat.food)
      }
      function Child(name,food){
        Parent.apply(this, Array.from(arguments))
      }
      Child.prototype = new Parent()
      Child.prototype.constructor = Child
      let child1 = new Child('aa', 'apple')
      let child2 = new Child('bb', 'orange')
      child1.actions()
      child2.actions()

缺点:调用了两次构造函数

寄生式组合继承

     function Parent(name, food){
        this.name = name
        this.eat = {food}
      }
      Parent.prototype.actions = function(){
        console.log(this.eat.food)
      }
      function Child(name,food){
        Parent.apply(this, Array.from(arguments))
      }
      Child.prototype = Object.create(Parent.prototype)
      Child.prototype.constructor = Child
      let child1 = new Child('aa', 'apple')
      let child2 = new Child('bb', 'orange')
      child1.actions()
      child2.actions()