数据劫持

195 阅读2分钟

数据劫持

在访问或者修改某个对象的属性时,通过一段代码进行拦截这个行为,会进行额外的操作或者修改返回的结果.

Object.defineProperty

可以利用Object.defineProperty方法给一个对象设置属性,可以添加get和set,当使用该属性的时候,会自动触发,get和set;当触发get和set,可以做条件判断和添加逻辑。

1.configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为false。

2.enumerable:表示能否通过for in循环访问属性,默认值为false

3.writable:表示能否修改属性的值。默认值为false。

4.value:包含这个属性的数据值。默认值为undefined。

getter和setter不能和以上的属性混合使用

Proxy

Proxy的定义:代理的意思。就是你想要对数据进行操作,必须经过代理,让代理去帮你操作数据,你只需要对代理发号施令就可以了。 相当于Proxy就是你的管家,你想买什么吃的,就跟管家说,管家会帮你去买。

  1. Proxy需要传进去两个参数,第一个你要代理的对象;第二个是handler,是你要对数据操作的一纺法。比如: get、 set方法等等。 2.实例化Proxy会返回一个代理对象。以后我们想要对target这个对象进行操作的时候,就对代理对象proxy进行操作就行了,它会帮我们去操作target对象的。
  2. get方法的形参:第一个参数:要操作的对象;第二个参数: 是你要操作的属性名。
  3. set方法的形参:第一和第二都和get方法的一样。第三个是你要设置的新的值。
  4. Reflect: 映射。就是将对象的方法映射到Reflect这个对象。由于target[prop] = value这个操作有可能产生异常,而使用 Reflect.set(target, prop, value) 这个函数调用,它内部会帮我们try catch,操作失败它会返回一个fasle, 就不至于导致程序异常。

与0bject.defineProperty的区别:

  • 1.都能够实现数据劫持

    1. Object.defineProperty是在原对象上进行数据劫持,而Proxy是对它返回的代理对象 上进行数据劫持。
    
      //一、proxy

      var person = {};

      var proxyObj = new Proxy(person, {
        get(target, property, value) {
          target[property];
        },
        set(target, property, value) {
          if (property == "name") {
            let reg = /[\u4e00-\u9fa5]/;
            if (reg.test(value)) {
              target[property] = value;
            }
          }
          if (property == "age") {
            if (value >= 18 && value <= 60) {
              target[property] = value;
            }
          }
        },
      });

      proxyObj.name = "熊阳";
      proxyObj.age = 20;
      console.log(person);

      //二、Object.defineProperty

      var student = {};
      var proxyObj = {};

      Object.defineProperty(proxyObj, "name", {
        get() {
            return student.name
        },
        set(value) {
          let reg = /[\u4e00-\u9fa5]/;
          if (reg.test(value)) {
            student.name = value;
          }
        },
      });

      Object.defineProperty(proxyObj, "age", {
        get() {
            return student.age
        },
        set(value) {
          if (value>=18&&value<=60) {
            student.age=value;
          }
        },
      });

      proxyObj.name="朗加";
      proxyObj.age=40
      console.log(student);

为了检查某个对象是否拥有不在原型链上的自定义属性,就有必要用到hasOwnProperty方法,相当于过滤原型的方法,任何一一个对象都具有该方法,它 继承自object.prototype。

原型重构数组方法

forEach

      Array.prototype.MyforEach = function (callbck) {
        for (var i = 0; i < this.length; i++) {
          console.log(this[i], i, this);
        }
      };

map

     Array.prototype.Mymap = function (callbck) {
        var list = [];
        for (var i = 0; i < this.length; i++) {
          list.push(callbck(this[i], i, this));
        }
        return list;
      };

some


      Array.prototype.Mysome = function (callbck) {
        for (let i = 0; i < this.length; i++) {
          if (callbck(this[i], i, this)) {
            return true;
          }
        }
        return false;
      };

every


     Array.prototype.Myevery = function (callbck) {
        for (let i = 0; i < this.length; i++) {
          if (!callbck(this[i], i, this)) {
            return false;
          }
        }
        return true;
      };

filter

      Array.prototype.Myfilter = function (callbck) {
        var arr3 = [];
        for (var i = 0; i < this.length; i++) {
          if (callbck(this[i], i, this)) {
            arr3.push(this[i]);
          }
        }
        return arr3;
      };

sort

     Array.prototype.MySort = function (callbck) {
        for (var i = 0; i < this.length - 1; i++) {
          for (var j = 0; j < this.length - 1 - i; j++) {
            if (callbck(this[j], this[j + 1]) > 0) {
              var temp = this[j];
              this[j] = this[j + 1];
              this[j + 1] = temp;
            }
          }
        }
        return this;
      };

reduce


     Array.prototype.Myreduce = function (callback, prev) {
        for (let i = 0; i < this.length; i++) {
          if (prev == null) {
            prev = callback(this[i], this[i + 1], i + 1, this);

            i++;
          } else {
            prev = callback(prev, this[i], i, this);
          }
        }
        return prev;
      };