给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
当前回答
我通过ninjagecko扩展了这个优雅的答案,这样函数就可以处理点和/或数组样式的引用,并且空字符串会导致父对象返回。
给你:
string_to_ref = function (object, reference) {
function arr_deref(o, ref, i) { return !ref ? o : (o[ref.slice(0, i ? -1 : ref.length)]) }
function dot_deref(o, ref) { return ref.split('[').reduce(arr_deref, o); }
return !reference ? object : reference.split('.').reduce(dot_deref, object);
};
查看我的jsFiddle工作示例:http://jsfiddle.net/sc0ttyd/q7zyd/
其他回答
这是我的实现
实现1
Object.prototype.access = function() {
var ele = this[arguments[0]];
if(arguments.length === 1) return ele;
return ele.access.apply(ele, [].slice.call(arguments, 1));
}
实现2(使用数组reduce而不是slice)
Object.prototype.access = function() {
var self = this;
return [].reduce.call(arguments,function(prev,cur) {
return prev[cur];
}, self);
}
例子:
var myobj = {'a':{'b':{'c':{'d':'abcd','e':[11,22,33]}}}};
myobj.access('a','b','c'); // returns: {'d':'abcd', e:[0,1,2,3]}
myobj.a.b.access('c','d'); // returns: 'abcd'
myobj.access('a','b','c','e',0); // returns: 11
它也可以处理数组中的对象
var myobj2 = {'a': {'b':[{'c':'ab0c'},{'d':'ab1d'}]}}
myobj2.access('a','b','1','d'); // returns: 'ab1d'
这是我的代码没有使用eval。这也很容易理解。
function value(obj, props) {
if (!props)
return obj;
var propsArr = props.split('.');
var prop = propsArr.splice(0, 1);
return value(obj[prop], propsArr.join('.'));
}
var obj = { a: { b: '1', c: '2', d:{a:{b:'blah'}}}};
console.log(value(obj, 'a.d.a.b')); // Returns blah
你可以用lodash。get
在安装(npm i lodash.get)后,像这样使用它:
const get = require('lodash.get');
const myObj = {
user: {
firstName: 'Stacky',
lastName: 'Overflowy',
list: ['zero', 'one', 'two']
},
id: 123
};
console.log(get(myObj, 'user.firstName')); // outputs Stacky
console.log(get(myObj, 'id')); // outputs 123
console.log(get(myObj, 'user.list[1]')); // outputs one
// You can also update values
get(myObj, 'user').firstName = 'John';
我不清楚你的问题是什么。给定你的对象,obj。a.b会给你原来的2。如果你想操纵字符串使用括号,你可以这样做:
var s = 'a.b';
s = 'obj["' + s.replace(/\./g, '"]["') + '"]';
alert(s); // displays obj["a"]["b"]
这是其中一种情况,你问10个开发人员,你会得到10个答案。
下面是我使用动态规划的OP[简化]解决方案。
其思想是,您将传递一个希望更新的现有DTO对象。这使得该方法在具有多个输入元素的表单的情况下最有用,这些输入元素的名称属性设置为圆点(fluent)语法。
使用示例:
<input type="text" name="person.contact.firstName" />
代码片段:
const setfluent = (obj, path, value) => { If (typeof path === "string") { 返回setfluent (obj, path.split("."), value); } 如果路径。长度<= 1){ Obj [path[0]] = value; 返回obj; } Const key = path[0]; obj[key] = setfluent (obj[key] ?)Obj [key]: {}, path.slice(1), value); 返回obj; }; const origObj = { 答:{ b:“1”, c:“2” } }; setfluent (origObj, "a.b", "3"); setfluent (origObj, "a.c", "4"); console.log (JSON。stringify(origObj, null, 3));