精华 写了一个模块 ettr,通过字符串描述访问嵌套属性
发布于 8 年前 作者 alsotang 3666 次浏览 最后一次编辑是 6 年前 来自 分享

地址在:https://github.com/alsotang/ettr

场景: 有时在得到一个 Object 之后,需要去访问里面嵌套的属性,但没法通过 literal 的方式来访问,于是就诞生了这样的一个库。


Build Status Coverage Status

install

npm install ettr

usage

Assume obj is

{
  a: {
    b: {
      c: 1,
      d: 2,
    }
  }
}

.get(obj, attr)

ettr.get(obj, 'a.b.c')
  .should.equal(1);

ettr.get(obj, 'a[b]["c"]')
  .should.equal(1);

.set(obj, attr, value)

ettr.set(obj, 'a.b.c', 5);
obj.a.b.c.should.equal(5);

.incr(obj, attr, value, defaultValue)

ettr.incr(obj, 'a.b.z', 1, 100);
ettr.incr(obj, 'a.b.z', 1, 100);
obj.a.b.z.should.equal(102);

license

MIT

14 回复

你可以再加上 -> 这个连接符 2333333。

这个模块式为防止读取内嵌对象时,出现以下问题而设计的吗?

a={
a:{}
};
var x = a.b.c;
TypeError: Cannot read property 'c' of undefined

建议跟py一样,读取get(obj, attr)时,第三个参数加上默认值

get(obj, attr, defaultValue)

@snoopy 不是不是,之所以做这个模块,是因为我想设计一个 ratelimit 方面的库。

这个库是以 connect 中间件的形式工作的,在这个库里面,通过配置的方式来决定 1. 以什么为 identity 2. 访问时间的控制如何。

在第 1 点中,由于我想支持字符串形式的写法,比如 user.\_id 或者 path 或者 header.x-forward-ip 这样的写法,所以开发了这个库。

@snoopy 如果配置作为一个 json 文件存在的话,那么配置拿不到 req 对象,就只能传递字符串给 ratelimit 库,让 ratelimit 去取出 req 的属性来。

codewars有这么一个题 http://www.codewars.com/kata/527a6e602a7db3456e000a2b

有best practice,我赶脚foreach不怎么好

Object.prototype.hash = function(string) {
  var obj = this;
  string.split(".").forEach(function(el) { 
    try {
      obj = obj[el];
    }
    catch(e) { 
      obj = undefined;
    }
  });
  return obj;
}

my_solution

// return the nested property value if it exists,
// otherwise return undefined
Object.prototype.hash = function(string) {
  // hash()
  if(!string) return this;
  
  if(typeof string === 'string')
    string = string.split('.')
  
  var ret = this[string[0]];
  if(string.length === 1){
    return ret
  }
  else{
    return ret 
      ? ret.hash(string.slice(1))
      : ret
  }
}

@magicdawn 这递归的写法也不错

找着一个很贱的写法

Object.prototype.hash = function(string) {
  var fn = new Function("try { return this." + string + "; } catch(e) {return undefined;} ");
  return fn.call(this);
}

@magicdawn 这种效率太低,跟用 eval 一样了。

@alsotang 也不是特别慢啊,node v0.11.14,10w次,4层深,170+ms , 关键是写起来方便

https://gist.github.com/magicdawn/d33604c651189267812c

@magicdawn

untitled1.png 我那个方法竟然是最慢的。。。肯定是因为我用了正则。。

@alsotang 我猜cpu 主频 3.25 GHz,这个中不?

@magicdawn

untitled1.png

应该是错了…

@alsotang 1.4呀呀呀!!! 肯定是睿频什么的,嗯.

回到顶部