OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

JavaScript中的哈希表(Hash Maps的最佳实践)


分享到
分类 JS学习   关键字 JavaScript   发布 ourjs  1433488574403
注意 转载须保留原文链接,译文链接,作者译者等信息。  
注* 散列表(Hash table,也叫哈希表),是根据关键字(Key value)而直接访问在内存存储位置的数据结构。摘自 Wiki

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

在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 {}


原文地址: 点此
社区评论 ( Beta版 )
  • #0 成火汉 1433497454449

    引用

  • #1 许亿此 1433732740810

    纯粹的键值对

  • #2 刘仇仓 1433907414666

    {}.hasOwnProperty.call(map, 'hasOwnproperty'); // true 这句会报错啊

  • #3 ourjs 1433909689557

    @刘仇仓 #2

    确实如此,可以写成:

    ({}).hasOwnProperty.call(map, 'hasOwnproperty');
    

    Object.hasOwnProperty.call(map, 'hasOwnproperty');
    
  • #4 Tyler 1435199526279

    Nice .

OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. 我是怎么从顾虑到热爱ReactJS的(与AngularJS经典MVC数据绑定的对比)
  2. 2015年度开发者调查:JS最流行;ObjC工资最高;最想学Android
  3. 基于JavaScript的DDoS首次通过安全的浏览器发动攻击(百度被劫持攻击Github的原理和过程)
  4. 编写高性能HTML网页应用
  5. 几款开源的图形化Redis客户端管理软件
  6. WordPress 4.3核心功能将放弃PHP并使用Node.JS重写[4.1]
  7. JavaScript变量作用域(Variable Scope)和闭包(closure)的基础知识
  8. Image Lazy Load:那些延时加载图片的开源插件(jQuery)
  9. 创建自定义的jQuery补间动画运动函数及其实现的数学原理
  10. JSON序列化(stringify)对象时排除某些属性的两种方法
  11. AirJD-简单好用的免费建站工具

 相关阅读 - JS学习
  1. 我是怎么从顾虑到热爱ReactJS的(与AngularJS经典MVC数据绑定的对比)
  2. JSON序列化(stringify)对象时排除某些属性的两种方法
  3. JavaScript变量作用域(Variable Scope)和闭包(closure)的基础知识
  4. 用jQuery为跳转链接锚点添加平滑滚动动画效果(如回到顶部按钮)
  5. 用纯css改变下拉列表select框的默认样式
  6. Atom编辑器嵌入Node.JS引擎实践
  7. AngularJS和$scope.$apply()用法的最佳实践
  8. 微软,IBM,ARM等大公司先后加入对Node.js/io.js的支持
  9. 用原生HTML5控件实现输入框自动提示(下拉列表补全)功能
  10. 让我们写快速的JavaScript,JS性能优化小窍门

 关键字 - JavaScript
  1. JavaScript中的继承,构造函数以及new关键字的作用
  2. 如何用CSS将select/option文本居中或居右对齐
  3. WowJS:在滚动页面时添加动画效果的简单实现
  4. NativeScript的工作原理:用JavaScript调用原生API实现跨平台
  5. 40行JavaScript代码实现的3D旋转魔方动画效果
  6. 如何通过网页、客户端、手机APP、路由器查找OnceAir NAS网盘的内网访问地址
  7. JavaScript数组从头开始的位置插入新元素或删除第一个元素
  8. 用JavaScript获取当月第一天和最后一天
  9. 我是怎么从顾虑到热爱ReactJS的(与AngularJS经典MVC数据绑定的对比)
  10. 在JavaScript中创建命名空间的几种写法

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号