详解JavaScript中Hash Map映射结构的实现


Posted in Javascript onMay 21, 2016

Hash Map通常在JavaScript中作为一个简单的来存储键值对的地方。然而,Object并不是一个真正的哈希映射,如果使用不当可能会带来潜在的问题。而且JavaScript可能不提供本地哈希映射(至少不是跨浏览器兼容的),有一个更好的声明对象属性的方法。

Hash Map的简单实现:

var hashMap = { 
  Set : function(key,value){this[key] = value}, 
  Get : function(key){return this[key]}, 
  Contains : function(key){return this.Get(key) == null?false:true}, 
  Remove : function(key){delete this[key]} 
}

使用方法示例:

hashMap.Set("name","John Smith"); 
hashMap.Set("age",24); 
hashMap.Get("name");//John Smith 
hashMap.Contains("title");//false 
hashMap.Contains("name");//true 
hashMap.Remove("age");

在Object声明成员的问题

该问题可能缘于对象原型链的继承机制。就拿toString方法来说,如果使用in操作符来判断对象是否存在的话:

var map = {};
'toString' in map; // true

因为in操作符会从所有原型继续对象查找该对象是否存在。要解决这个问题,可使用hasOwnProperty方法检测该对象是否存在:

var map = {};
map.hasOwnProperty('toString'); // false

这个方法可以工作地很正常,不过如果你定义了一个hasOwnProperty属性那可能就麻烦了:

var map = {};
map.hasOwnProperty = 'foo';
map.hasOwnProperty('hasOwnproperty'); // TypeError

快速修复这个的方法是使用原生对象的方法。

var map = {};
map.hasOwnProperty = 'foo';
{}.hasOwnProperty.call(map, 'hasOwnproperty'); // true

这种方法不会引起任何问题,每次你判断对象中的属性是否存在时都要过滤掉原型链中的方法:

var map = {};
var has = {}.hasOwnProperty;

for(var key in map){
 if(has.call(map, key)){
  // do something
 }
}

裸对象

创建一个真正的Hash Map的诀窍是解藕所有的原型对象。我们可以通过 Object.create 来实现这个效果

var obj = {};
// is equivalent to:
var obj = Object.create(Object.prototype);

另外,这种方法可以让你完全放弃原型,直接使用 null 来继承。

var map = Object.create(null);

map instanceof Object; // false
Object.prototype.isPrototypeOf(map); // false
Object.getPrototypeOf(map); // null

这些裸对象(或字典)是作为Hasp Map的理想选择。因为不会有任何冲突,它会抵制任何类型转换,比如这样就会产生错误。

var map = Object.create(null);
map + ""; // TypeError: Cannot convert object to primitive value

这里没有任何保留字,它就是为Hash Map设计的,比如。

var map = Object.create(null);
'toString' in map; // false
更进一步,for ... in 循环变得更加简单了,我们只需要把循环写成这样。
var map = Object.create(null);

for(var key in map){
 // do something
}

除了这些区别,它使用起来跟一般的Object键值存储没有任何区别。该对象可以被序列化,可以声明原型和被继承,上下文变量的使用也是一样的。

var map = Object.create(null);

Object.defineProperties(map, {
 'foo': {
  value: 1,
  enumerable: true
 },
 'bar': {
  value: 2,
  enumerable: false
 }
});

map.foo; // 1
map['bar']; // 2

JSON.stringify(map); // {"foo":1}

{}.hasOwnProperty.call(map, 'foo'); // true
{}.propertyIsEnumerable.call(map, 'bar'); // false

甚至上面提到的那些变量检测方法同样适用。

var map = Object.create(null);

typeof map; // object
{}.toString.call(map); // [object Object]
{}.valueOf.call(map); // Object {}
Javascript 相关文章推荐
javascript的函数
Jan 31 Javascript
Extjs Ext.MessageBox.confirm 确认对话框详解
Apr 02 Javascript
javascript cookies操作集合
Apr 12 Javascript
jQuery常用操作方法及常用函数总结
Jun 19 Javascript
javascript通过元素id和name直接取得元素的方法
Apr 28 Javascript
详解如何在vue中使用sass
Jun 21 Javascript
微信小程序与php 实现微信支付的简单实例
Jun 23 Javascript
详解ES6之async+await 同步/异步方案
Sep 19 Javascript
用JS实现根据当前时间随机生成流水号或者订单号
May 31 Javascript
Bootstrap模态对话框中显示动态内容的方法
Aug 10 Javascript
JavaScript的级联函数用法简单示例【链式调用】
Mar 26 Javascript
浅谈小程序globalData的那些事儿
Nov 01 Javascript
简单掌握JavaScript中const声明常量与变量的用法
May 21 #Javascript
基于javascript实现表格的简单操作
May 21 #Javascript
javascript检测移动设备横竖屏
May 21 #Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
May 21 #Javascript
js+html5实现canvas绘制网页时钟的方法
May 21 #Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
May 21 #Javascript
javascript RegExp 使用说明
May 21 #Javascript
You might like
用文本文件制作留言板提示(下)
2006/10/09 PHP
深入理解PHP 数组之count 函数
2016/06/13 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
微信封装的调用微信签名包的类库
2017/06/08 PHP
PHP实现微信公众号验证Token的示例代码
2019/12/16 PHP
jquery图片上下tab切换效果
2011/03/18 Javascript
使用jQuery判断IE浏览器版本的代码
2014/06/14 Javascript
JavaScript中遍历对象的property的3种方法介绍
2014/12/30 Javascript
javascript编写实用的省市选择器
2015/02/12 Javascript
JQuery显示隐藏页面元素的方法总结
2015/04/16 Javascript
不用一句js代码初始化组件
2016/01/27 Javascript
清除js缓存的多种方法总结
2016/12/09 Javascript
兼容浏览器的js事件绑定函数(详解)
2017/05/09 Javascript
详解webpack babel的配置
2018/01/09 Javascript
浅谈vue.js导入css库(elementUi)的方法
2018/03/09 Javascript
JS将网址url转化为JSON格式的方法
2018/07/02 Javascript
详解使用WebPack搭建React开发环境
2019/08/06 Javascript
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
2019/09/05 Javascript
Django中模型Model添加JSON类型字段的方法
2015/06/17 Python
python解决Fedora解压zip时中文乱码的方法
2016/09/18 Python
tensorflow入门之训练简单的神经网络方法
2018/02/26 Python
Python随机生成身份证号码及校验功能
2018/12/04 Python
解决pycharm回车之后不能换行或不能缩进的问题
2019/01/16 Python
解决pycharm中导入自己写的.py函数出错问题
2020/02/12 Python
python虚拟环境模块venv使用及示例
2020/03/04 Python
python温度转换华氏温度实现代码
2020/12/06 Python
使用OpenCV实现人脸图像卡通化的示例代码
2021/01/15 Python
打造经典复古风格的品牌:Alice + Olivia(爱丽丝+奥利维亚)
2016/09/07 全球购物
Kivari官网:在线购买波西米亚服装
2018/10/29 全球购物
世界上最好的足球商店:Unisport
2019/03/02 全球购物
开办加工厂创业计划书
2014/01/03 职场文书
省优秀教师事迹材料
2014/01/30 职场文书
三月学雷锋月活动总结
2014/04/28 职场文书
副总经理岗位职责
2015/02/02 职场文书
质量整改通知单
2015/04/21 职场文书
Javascript 解构赋值详情
2021/11/17 Javascript