#61 监听数组变化


  • 0
    administrators

    在前端的 MVVM 框架当中,我们经常需要监听数据的变化,而数组是需要监听的重要对象。请你完成 ObserverableArray,它的实例和普通的数组实例功能相同,但是当调用:

    • push
    • pop
    • shift
    • unshift
    • splice
    • sort
    • reverse

    这些方法的时候,除了执行相同的操作,还会把方法名打印出来。 例如:

    const arr = new ObserverableArray()
    
    arr.push('Good') // => 打印 'push',a 变成了 ['Good']
    

    注意,你不能修改 Array 的 prototype。还有函数 return 的值和原生的操作保持一致。


  • 0

    用Proxy求解就很简单了。。。

    function ObserverableArray(...p) {
      return new Proxy(new Array(...p), {
        get(target, property) {
          const ret = target[property]
          if (typeof ret === 'function')
            return function (...p){ console.log(property); return ret.apply(this, p) }
          return ret
        }
      })
    }
    

  • 0

    @CodeHz#61 监听数组变化 中说:

    Proxy

    不用Proxy要怎么做


  • 0

    @caffrey 比如直接用继承。。。然后覆盖那几个方法,顺便调用基类方法什么的


  • 0
    administrators

    这道题如果用 ES5 的继承方式,最好不要产生和对原生数组的 for in 操作不一致的行为。

    例如:

    var a = ObserverableArray()
    for (let key in a) console.log(key)
    

    原生数组是不糊把 push、pop、...这些方法遍历出来的。你的实现最好也不要遍历这些属性。


  • 0
    管理员

    调用push方法 console.log的次数不对?有点奇怪了这个报错

    function ObserverableArray() {
      return new Proxy([], {
        get(target, propKey) {
          typeof target[propKey] == 'function' && console.log(propKey);
          return target[propKey]
        }
      })
    }
    

  • 0
    administrators

    @陈小俊 这种方式其实是不符合题意的。

    这样会导致所有函数都会打印内容,例如 forEach,而题目只要求 7 个方法。


  • 0
    管理员

    @胡子大哈 哦哦


  • 0
    管理员

    function ObserverableArray() {
      return new Proxy([], {
        get(target, propKey) {
          const matArr = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
          matArr.indexOf(propKey) > -1 && console.log(propKey);
          return target[propKey]
        }
      })
    }
    

  • 0

    我觉得很奇怪,我的arrMethods如果是[],就是ac,如果是{},就是返回的是需要时数组0_1496665756372_upload-a5c0e414-b233-4a57-9a0e-4a554b9ad344

    function ObserverableArray (){
      var arr = new Array();
      var arrMethodsName = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
      var arrMethods = [];
      arrMethodsName.forEach(function(method, index) {
        let original = Array.prototype[method];
        arrMethods[method] = function () {
          console.log(`${method}`);
          return original.apply(this, arguments);
        }
      })
      arr.__proto__ = arrMethods;
      return arr;
    }
    

登录后回复
 

与 ScriptOJ 的连接断开,我们正在尝试重连,请耐心等待