javaScript Map对象详解

这节给大家详细解析下js自带MAp对象,平时大家估计很少用到这个东西。注意这里不是讲map标签,map标签只是对自定义区域的一个坐标定位需要配合area进行相关视图定位操作;而Map对象是和一样Object、Array js原生自带的一个构造函数,可自行new出你的自定义对象进行内存分配,那么我们来看以下代码:

let obj=newObject();//创建你的对象

let array=newArray();//创建你的数组

//当然js是弱类型语言,很多方面并不严谨,

//就比如新建json数据对象我们直接可以

let json={a:1};

//同理数组

let newArray=[];

.........

/*当然在规则里面js对象包含字符串、

*数值、数组、函数、json、Number.....

*/

//比如我们还可以这样创建一个数组或者数字

let temp=newObject([1,2,3])==>[1,2,3]

let number=newObject(5)==>5

以上简单介绍到这里 那么我们新建Map对象也同理

创建你的键/值对的集合【其实就是个类数组,下面会详细阐述】

let myMapObject = new Map();

Map ==> 是原生构造函数

Prototype原形自带size【属性】 return 返回映射中的元素个数

就是你往你的Map里塞了几个元素 新建对象可直接调用:

let myMapSize = myMapObject.size;

方法描述:

clear --- 从映射中移除所有元素。

delete --- 从映射中移除指定的元素。

forEach --- 对映射中的每个元素执行指定操作。

get --- 返回映射中的指定元素。

has --- 如果映射包含指定元素,则返回 true。

set --- 添加一个新建元素【可以是任何类型】到映射。

toString --- 返回映射的字符串表示形式。

valueOf --- 返回指定对象的原始值。

//给我们的Map对象赋值看看

myMapObject.set('name',"林远风");

myMapObject.set('sex',"男");

myMapObject.set(1,[1,2,3]);

上面我为什么说他是一个类数组呢?那么我们来看Map对象,如下图

Entries下面的所有类目相似一个数组 只是 值方面并不是一个对象而是一个箭头写法 暂且认为他是json字符串的写法,他并不是一个对象,不再有Prototype原形和指针属性; 如果学过php的就比较熟悉 php定义数组 $arr = [a=>123,b=>'456'];有异曲同工之妙;其实它是一个迭代器。

下面再看一个普通数组来对比Map,如图:

//新建一个普通数组 结果要和Map对象相似

let arr=[

{'name':'林远风'},

{'sex':'男'},

{1:[1,2,3]}

];

数组对象同样自带length属性

只是把值直接给你解析出来了 每个键对应的值也是一样对象。

Map把你设置的键/值内容强制赋值到Entries下面了。

那么他们之间有有何区别呢?

1、Map对象提供了快速获取某个属性的方法 比如我要获取name属性

//Map对象获取属性值

let myName=myMapObject.get('name');

console.log('myName---',myName);

//output ==> 林远风

//那么上面那个数组要怎么获取呢?

//获取固定格式数组的某个键值

/*eg: arr = [

{'name':'林远风'},

{'sex':'男'},

];*/

constgetArrVal=function(arr,key){

let result=null;

arr.forEach(function(val,index,arr){

let _key=Object.keys(val)[];

if(_key===key){

result=val[key];

}

})

returnresult;

}

let myName=getArrVal(arr,'name');

console.log('myName---',myName);

//output ==> 林远风

观看以上两种最终结果都是一样的,但是写法上Map却是不一样。

当然即使没有原生自带的Map构造函数 我们也可以自己构造一个,根据上面的固定数组格式反向即可构造

eg :

//原型链构造Map2

classMap2{

constructor(){

//用于创建json数据对象

this.creatJson=function(key,value){

let json={};

json['key']=key;

json['value']=value;

returnjson;

};

//用于储存json数据对象

this.arr=[];

//返回Mapsize

this.size=;

}

set(key,value){

letself=this;

//先索引一遍原数组是否要更新

for(let i=;i

if(self.arr[i].key===key){

self.arr[i].value=value;

return;

}

}

//若是新增则数组新加对象

self.arr[self.arr.length]=self.creatJson(key,value);

//对size赋值

self.size=self.arr.length;

}

get(key){

letself=this;

for(let i=;i

if(self.arr[i].key===key){

returnself.arr[i].value;

}

}

returnnull;

}

_delete(key){

letself=this;

/*由于val可以是任何值

*这里我们不能用简单的splice来进行数组删除操作

*这里用末尾追加的方法 但会改变原数组的排序

*不过并不会影响取值赋值等操作

*/

let val;

for(let i=;i

//删除最后一个元素返改变原数组长度-1 并保存当前值

val=self.arr.pop();

if(val.key===key){

//迭代下一个循环 不在进行unshift操作

continue;

}

//新数组重新塞到原数组前面 修改原有的数组长度

self.arr.unshift(val);

}

//对size赋值

self.size=self.arr.length;

}

........

}

var_map2=newMap2();

_map2.set("name",'林大仙');

_map2.set("json",{a:1});

let myName=_map2.get('name');

console.log('myName--',myName);

//output==>林大仙

可以看出我们自己构建的构造函数也是能达到原生Map的效果当然他的构造跟Map是不一样的 如图:

我们新建的Map2==>

原生Map==>

但是Map对象是怎么取值的呢?这里引入一个迭代对象的概念,我们新建的Map()就是一个可迭代的对象。那么[[Entries]]这个就是他的迭代器了!其实他是Map.entries的返回值, Map.entries()返回的就是当前Map对象的迭代器那么我们可以模拟Map.get()取值过程

//还是用我们之前创建的 myMapObject 对象

let getVal=function(key){

//迭代器

let mapIterator=myMapObject.entries();

/*

*这里我们循环myMapObject迭代对象

*也一样系统会自动找到他的迭代器

*/

for(let[_key,val]of mapIterator){

if(_key===key){

returnval;

}

}

returnnull;

}

let myName=getVal('name');

console.log('myName--',myName);

//output==>林远风

//等同于

myMapObject.get('name');

而我们自己创建的方法则是循环数组查找这就务必要消耗内存,那么现在是系统自带的迭代器算法自然比我们自己定义的速度快啦.... 迭代器 生成器参考地址

好了,基本Map的概述和相关原理已经解析的十分透彻了,那么我们可以用它来做什么呢?

如果用来作为全局对象引用

const App = new Map();

然而新建的对象失去了this指针的概念显然不是很合理,所以我们全局公用数据方法一般是用Object来储存

const App = };

所以Map对象更适用于不同模块的场景。这样我们可以公用的同时也能自行管理维护。解决Object运用于全局场景,多人开发时候的时候新增删减的麻烦。如果你想要键值对的数据结构Map比Object更合适。eg:

//app.js

constApp=newMap();

exportdefaultApp;

//myMap.js

importAppfrom'./app.js';

//用户模块

varrenderUserData=function(pram){

console.log('pram',pram);

//output=>

//处理数据并渲染

}

App.set('userData',renderUserData);

//其他模块

........

exportdefaultApp;

//page.js

importmyMapfrom'./myMap.js';

//取值并执行Map方法

myMap.get('userData')({name:'林远风',sex:'男'});

这样一来我们每个人就能自行维护自己的模块page.js处理数据获取 myMap.js处理数据和页面逻辑即使我们的map命名与别人的相同了也无须理会,因为在你的页面set数据就是最新的,但要注意固定不变的数据应该统一写在app.js里。

这期关于Map对象就讲到这,如果还有什么问题或者其他想了解的,可以给我留言。主页右下角点开留言图标。

生命不止,学无止境,既然长得丑又没钱你还不努力?---- 李时珍.皮。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180328G1VTK900?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券