객체의 특정 값을 안전하게 가져오는 함수를 만들었다.
자바스크립트에서 객체의 값을 에러 없이 안전하게 가져오는 방법이 필요했다.
person.name
처럼 간단한 패스는 쉽게 유추 가능하지만, 그렇지 않은 경우가 더 많다.
a.b.c.d.e.f.g.h.i.j.k
처럼 깊은 패스의 데이터는 다음과 같이 간단하게 가져올 수 있지만, 매번 이렇게 데이터를 가져오는 것은 불필요하고 소모적이다.
try {
return obj.a.b.c.d.e.f.g.h.i.j.k;
} catch (e) {
throw e;
}
구현한 함수(가칭으로 search
라고 하자)를 사용하면
다음과 같이 값을 가져올 수 있다.
var person = {
name: 'Anthony',
age: 20,
birth: '1996-04-20',
hobby: ['reading', 'singing'],
friends: [{
name: 'Scully',
age: 20,
birth: '1996-01-20'
}, {
name: 'Sienna',
age: 18,
birth: '1998-04-20'
}]
};
search('name', person);
search('friends[0].name', person);
구현은 다음과 같다.
define(function () {
var trampoline = function (f) {
while (f && f instanceof Function) {
f = f.apply(f.context, f.args);
}
};
return function (path, obj) {
var paths = path.replace(/\[/g,'.').replace(/\]/g,'').split('.'),
safety = function (f) { try { return f(); } catch (e) { return "";}},
getValue = function (keys, target) {
var f = function (_key, _target, _keys) {
var _value = _target[_key];
return _keys.length === 0 ? _value : f.call(null, _keys.shift(), _value, _keys);
}
return trampoline(f.call(null, keys.shift(), target, keys));
};
var v = safety(function () {
return getValue.call(null, paths, (obj || this));
});
return (typeof v !== "undefined" && v !== null) ? v : "";
};
});
nono template을 보고 영감을 얻어 만들었다. nano template과 다른점은 배열의 데이터도 가져올 수 있다는 것.
trampoline 함수는 재귀함수 스택이 많아질 때 성능의 개선이 있다고 하는 글을 보고 간단하게 넣었다.