详解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 相关文章推荐
jqeury eval将字符串转换json的方法
Jan 20 Javascript
jQuery实现隔行背景色变色
Nov 24 Javascript
Jquery解析json字符串及json数组的方法
May 29 Javascript
JavaScript的React框架中的JSX语法学习入门教程
Mar 05 Javascript
AngularJS入门教程之服务(Service)
Jul 27 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
Aug 03 Javascript
JavaScript实现时钟滴答声效果
Jan 29 Javascript
详解Vue.js入门环境搭建
Mar 17 Javascript
Node.js开发第三方微信公众平台
Jun 05 Javascript
JavaScript面向对象的程序设计(犯迷糊的小羊)
May 27 Javascript
Vue组件间通信方法总结(父子组件、兄弟组件及祖先后代组件间)
Apr 17 Javascript
Vue中key的作用示例代码详解
Jun 10 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
山进SANGEAN ATS-909X电路分析
2021/03/02 无线电
PHP中空字符串介绍0、null、empty和false之间的关系
2012/09/25 PHP
PHP循环输出指定目录下的所有文件和文件夹路径例子(简单实用)
2014/05/10 PHP
php中将一个对象保存到Session中的方法
2015/03/13 PHP
php清除和销毁session的方法分析
2015/03/19 PHP
javascript 学习之旅 (1)
2009/02/05 Javascript
prototype与jquery下Ajax实现的差别
2009/09/13 Javascript
javascript 基础篇4 window对象,DOM
2012/03/14 Javascript
node.js中的fs.readdirSync方法使用说明
2014/12/17 Javascript
JavaScript中的DSL元编程介绍
2015/03/15 Javascript
禁止按回车键提交表单的方法
2015/06/11 Javascript
javascript中不易分清的slice,splice和split三个函数
2016/03/29 Javascript
javascript jquery对form元素的常见操作详解
2016/06/12 Javascript
JS图片左右无缝隙滚动的实现(兼容IE,Firefox 遵循W3C标准)
2016/09/23 Javascript
jQuery+ThinkPHP+Ajax实现即时消息提醒功能实例代码
2017/03/21 jQuery
vue2里面ref的具体使用方法
2017/10/27 Javascript
vue2 mint-ui loadmore实现下拉刷新,上拉更多功能
2018/03/21 Javascript
详解ES6 系列之异步处理实战
2018/10/26 Javascript
vue.js实现数据库的JSON数据输出渲染到html页面功能示例
2019/08/03 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
python获取文件扩展名的方法
2015/07/06 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
2019/06/27 Python
python用for循环求和的方法总结
2019/07/08 Python
2020年10款优秀的Python第三方库,看看有你中意的吗?
2021/01/12 Python
使用JS+CSS3技术:让你的名字动起来
2013/04/27 HTML / CSS
CSS3 实现的缩略图悬停效果
2020/12/09 HTML / CSS
加拿大当代时尚服饰、配饰和鞋类专业零售商和制造商:LE CHÂTEAU
2017/10/06 全球购物
Chicco婴儿用品美国官网:汽车座椅、婴儿推车、高脚椅等
2018/11/05 全球购物
客户代表实习人员自我鉴定
2013/09/27 职场文书
群众路线对照检查剖析材料
2014/10/09 职场文书
2015年酒店工作总结范文
2015/04/07 职场文书
小区环境卫生倡议书
2015/04/29 职场文书
东京审判观后感
2015/06/01 职场文书
幼儿园老师新年寄语
2015/08/17 职场文书
电脑无法安装Windows 11怎么办?无法安装Win11的解决方法
2021/11/21 数码科技