假設我們只給如何在JavaScript中給定其字符串名稱的對象屬性(的..的對象屬性)?
var obj = {};
var propName = "foo.bar.foobar";
我們怎樣才能物業obj.foo.bar.foobar
設置爲特定值(顯示 「Hello World」)? 所以我想做到這一點,而我們只在一個字符串有屬性名稱:
obj.foo.bar.foobar = "hello world";
假設我們只給如何在JavaScript中給定其字符串名稱的對象屬性(的..的對象屬性)?
var obj = {};
var propName = "foo.bar.foobar";
我們怎樣才能物業obj.foo.bar.foobar
設置爲特定值(顯示 「Hello World」)? 所以我想做到這一點,而我們只在一個字符串有屬性名稱:
obj.foo.bar.foobar = "hello world";
function assign(obj, prop, value) {
if (typeof prop === "string")
prop = prop.split(".");
if (prop.length > 1) {
var e = prop.shift();
assign(obj[e] =
Object.prototype.toString.call(obj[e]) === "[object Object]"
? obj[e]
: {},
prop,
value);
} else
obj[prop[0]] = value;
}
var obj = {},
propName = "foo.bar.foobar";
assign(obj, propName, "Value");
因爲這個問題似乎是由不正確的答案來回答,我只是指從a similar question
正確的答案function setDeepValue(obj, value, path) {
if (typeof path === "string") {
var path = path.split('.');
}
if(path.length > 1){
var p=path.shift();
if(obj[p]==null || typeof obj[p]!== 'object'){
obj[p] = {};
}
setDeepValue(obj[p], value, path);
}else{
obj[path[0]] = value;
}
}
用途:
var obj = {};
setDeepValue(obj, 'Hello World', 'foo.bar.foobar');
嗯。你的答案看起來像我的一個確切的副本:) – VisioN
它看起來像我在'typeof'中遺漏了'='。但坦率地說,'typeof'是唯一確保你不會分裂對象的方法,這是我碰到的一個問題。其餘的,這是簡單的遞歸。 – Cerbrus
如果我用'foo.bar.foobar'和'foo.bar2.foobar2'調用它兩次會怎樣? – FrancescoMM
編輯:我ç重新編號爲jsPerf.com testcase以將接受的答案與我的版本進行比較。 原來我的版本更快,尤其是當你深入的時候。
var nestedObjectAssignmentFor = function(obj, propString, value) {
var propNames = propString.split('.'),
propLength = propNames.length-1,
tmpObj = obj;
for (var i = 0; i <= propLength ; i++) {
tmpObj = tmpObj[propNames[i]] = i !== propLength ? {} : value;
}
return obj;
}
var obj = nestedObjectAssignment({},"foo.bar.foobar","hello world");
這裏是一個get和set功能,我剛剛從一對夫婦線程+一些自定義代碼的編譯。
它還會創建集合中不存在的密鑰。
function setValue(object, path, value) {
var a = path.split('.');
var o = object;
for (var i = 0; i < a.length - 1; i++) {
var n = a[i];
if (n in o) {
o = o[n];
} else {
o[n] = {};
o = o[n];
}
}
o[a[a.length - 1]] = value;
}
function getValue(object, path) {
var o = object;
path = path.replace(/\[(\w+)\]/g, '.$1');
path = path.replace(/^\./, '');
var a = path.split('.');
while (a.length) {
var n = a.shift();
if (n in o) {
o = o[n];
} else {
return;
}
}
return o;
}
所有的解決方案設置,所以我有一個具有以下扭捏的時候overid任何原始數據,使它成爲一個單一的對象太:
var obj = {}
nestObject.set(obj, "a.b", "foo");
nestObject.get(obj, "a.b"); // returns foo
var nestedObject = {
set: function(obj, propString, value) {
var propNames = propString.split('.'),
propLength = propNames.length-1,
tmpObj = obj;
for (var i = 0; i <= propLength ; i++) {
if (i === propLength){
if(tmpObj[propNames[i]]){
tmpObj[propNames[i]] = value;
}else{
tmpObj[propNames[i]] = value;
}
}else{
if(tmpObj[propNames[i]]){
tmpObj = tmpObj[propNames[i]];
}else{
tmpObj = tmpObj[propNames[i]] = {};
}
}
}
return obj;
},
get: function(obj, propString){
var propNames = propString.split('.'),
propLength = propNames.length-1,
tmpObj = obj;
for (var i = 0; i <= propLength ; i++) {
if(tmpObj[propNames[i]]){
tmpObj = tmpObj[propNames[i]];
}else{
break;
}
}
return tmpObj;
}
};
還可以更改的功能是一個Oject.prototype方法變更的obj參數去這樣的:
Object.prototype = { setNested = function(){ ... }, getNested = function(){ ... } }
{}.setNested('a.c','foo')
這裏有一個返回更新的對象
function deepUpdate(value, path, tree, branch = tree) {
const last = path.length === 1;
branch[path[0]] = last ? value : branch[path[0]];
return last ? tree : deepUpdate(value, path.slice(1), tree, branch[path[0]]);
}
const path = 'cat.dog';
const updated = deepUpdate('a', path.split('.'), {cat: {dog: null}})
// => { cat: {dog: 'a'} }
這是一個簡單的函數來做這個使用參考。
function setValueByPath (obj, path, value) {
var ref = obj;
path.split('.').forEach(function (key, index, arr) {
ref = ref[key] = index === arr.length - 1 ? value : {};
});
return obj;
}
您可以拆分路徑並檢查是否存在以下元素。如果不將對象分配給新屬性。
然後返回屬性的值。
最後賦值。
function setValue(object, path, value) {
var fullPath = path.split('.'),
way = fullPath.slice(),
last = way.pop();
way.reduce(function (r, a) {
return r[a] = r[a] || {};
}, object)[last] = value;
}
var object = {},
propName = 'foo.bar.foobar',
value = 'hello world';
setValue(object, propName, value);
console.log(object);
沒有遞歸或回調開銷。
function setDeepVal(obj, path, val) {
var props = path.split('.');
for (var i = 0, n = props.length - 1; i < n; ++i) {
obj = obj[props[i]] = obj[props[i]] || {};
}
obj[props[i]] = val;
return obj;
}
// TEST
var obj = { hello : 'world' };
setDeepVal(obj, 'foo.bar.baz', 1);
setDeepVal(obj, 'foo.bar2.baz2', 2);
console.log(obj);
重複的http://stackoverflow.com/questions/6842795/dynamic-deep-setting-for-a-javascript-object – Cerbrus
這可能幫助別人誰是試圖瞭解這個問題的答案問題... http://stackoverflow.com/questions/39060905/how-recursion-takes-place-in-this-code-snippet –