来自 Web前端 2020-04-29 17:43 的文章
当前位置: 网上澳门金莎娱乐 > Web前端 > 正文

typescript中继承Array、Map、Set报错的解决

时间: 2019-09-07阅读: 167标签: map

前言
上一篇文章我们实现了一个属于自己的简易MVVM库,里面实现了一个mvvm库应有基本功能,里面对数据进行了数据劫持,但是仅仅只是对对象进行了数据劫持,并没有实现数组的一个监听。今天我将带着大家实现数组的observe。

Map、Set的polyfill实现是可以继承的

一、整体思路
1、定义变量arrayProto接收Array的prototype2、定义变量arrayMethods,通过Object.create()方法继承arrayProto3、重新封装数组中push,pop等常用方法。(这里我们只封装我们需要监听的数组的方法,并不做JavaScript原生Array中原型方法的重写的这么一件暴力的事情)4、更多的奇淫技巧探究
二、监听数组变化实现
这里我们首先需要确定的一件事情就是,我们只需要监听我们需要监听的数据数组的一个变更,而不是针对原生Array的一个重新封装。
其实代码实现起来会比较简短,这一部分代码我会直接带着注释贴出来

if(不支持Map){//polyfill}else{(function(){//可继承Map替代原生Mapvar GMap=globalThis.Map;try{Map.call({});}catch(e){globalThis.Map=function(args){var map=new GMap(args);Object.setPrototypeOf(map,Object.getPrototypeOf(this));return map;};Map.prototype=GMap.prototype;}})();}

if(不支持Set){//polyfill}else{(function(){//可继承Set替代原生Setvar GSet=globalThis.Set;try{Set.call({});}catch(e){globalThis.Set=function(args){var set=new GSet(args);Object.setPrototypeOf(set,Object.getPrototypeOf(this));return set;};Set.prototype=GSet.prototype;}})();}
// 获取Array原型
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
const newArrProto = [];
[
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
].forEach(method => {
  // 原生Array的原型方法
  let original = arrayMethods[method];

  // 将push,pop等方法重新封装并定义在对象newArrProto的属性上
  // 这里需要注意的是封装好的方法是定义在newArrProto的属性上而不是其原型属性
  // newArrProto.__proto__ 没有改变
  newArrProto[method] = function mutator() {
    console.log('监听到数组的变化啦!');

    // 调用对应的原生方法并返回结果(新数组长度)
    return original.apply(this, arguments);
  }
})

let list = [1, 2];
// 将我们要监听的数组的原型指针指向上面定义的空数组对象
// newArrProto的属性上定义了我们封装好的push,pop等方法
list.__proto__ = newArrProto;
list.push(3);  // 监听到数组的变化啦! 3

// 这里的list2没有被重新定义原型指针,所以这里会正常执行原生Array上的原型方法
let list2 = [1, 2];
list2.push(3);  // 3

Array要改的地比较多,

目前为止我们已经实现了数组的监听。从上面我们看出,当我们将需要监听的数组的原型指针指向newArrProto对象上的时候(newArrProto的属性上定义了我们封装好的push,pop等方法)。这样做的好处很明显,不会污染到原生Array上的原型方法。

(function(){//可继承的Array替换原生Arrayvar GArray=globalThis.Array;function Array(){var arr=GArray.apply(this,arguments);if(this.constructor===GArray){//new调用return arr || this;}else{//super调用this.length=arr.length;Object.assign(this,arr);} }Array.prototype=GArray.prototype;Array.from=GArray.from;Array.of=GArray.of;Array.isArray=GArray.isArray;globalThis.Array=Array;})();

三、更多的奇淫技巧

本文由网上澳门金莎娱乐发布于Web前端,转载请注明出处:typescript中继承Array、Map、Set报错的解决

关键词: