CNode

写了一个模块 ettr,通过字符串描述访问嵌套属性

精华
分享
Aalsotang发布于12 年前最后回复12 年前14 回复5566 浏览0 收藏

地址在: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)

M
magicdawn#2·12 年前

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
  }
}
M
magicdawn#4·12 年前

找着一个很贱的写法

Object.prototype.hash = function(string) {
  var fn = new Function("try { return this." + string + "; } catch(e) {return undefined;} ");
  return fn.call(this);
}
A
alsotang#5·12 年前
引用 magicdawn找着一个很贱的写法

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

M
magicdawn#6·12 年前
引用 alsotang@magicdawn 这种效率太低,跟用 eval 一样了。

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

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

A
alsotang#7·12 年前
M
magicdawn#10·12 年前
引用 alsotang@magicdawn 应该是错了..

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

X
XadillaX#11·12 年前

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

D
DoubleSpout#12·12 年前

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

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

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

get(obj, attr, defaultValue)
A
alsotang#13·12 年前
引用 DoubleSpout这个模块式为防止读取内嵌对象时,出现以下问题而设计的吗? a={ a:{} }; var x = a.b.c; TypeError: Cannot read property 'c' of u...

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

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

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

A
alsotang#14·12 年前
引用 DoubleSpout这个模块式为防止读取内嵌对象时,出现以下问题而设计的吗? a={ a:{} }; var x = a.b.c; TypeError: Cannot read property 'c' of u...

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

参与回复
登录后即可参与回复。登录