添加到可能存在或可能不存在的json属性

我想说我想这样做:

var dashboard = {}; var page = "index"; $('.check').click(function(){ $(this).toggleClass("active").siblings().slideToggle('slow', function() { dashboard['pages'][page][$(this).closest('li').attr("id")]['show'] = $(this).is(":hidden") ? 'collapsed' : 'expanded'; }); } 

我收到一个错误说:

Dashboard.pages未定义

有没有动态添加pages和后面的子项,而不必进行检查工作,看它是否先被定义,然后如果它没有这样做:

  dashboard['pages'] = {}; 

因为有时它们可​​能已经存在,我不想首先检查树,我只是想根据需要构建分支

编辑我将pagename名称更改为page以显示页面名称将更改,我还想指出页面可能真的是任何东西。 这个想法是你有任何对象可以包含带参数的对象,而不检查分支是否存在

它看起来像$extend那样只是不确定它是如何工作的。 得到我的头脑。

Object上定义get和set方法。 实际上,它可以只在dashboard对象上定义,只有它的后代,但这很容易。

 Object.prototype.get = function(prop) { this[prop] = this[prop] || {}; return this[prop]; }; Object.prototype.set = function(prop, value) { this[prop] = value; } 

使用此get()方法迭代嵌套属性,并在必须设置值时调用set()

 var dashboard = {}; dashboard.get('pages').get('user').set('settings', 'oh crap'); // could also set settings directly without using set() dashboard.get('pages').get('user').settings = 'oh crap'; console.log(dashboard); //​​​​​​​​​​​​​​​ {pages: {user: {settings: "oh crap"}}}; 

您还可以扩展/修改get方法,以将嵌套属性作为单个参数数组字符串接受。 使用它,你只需要调用get一次:

 // get accepts multiple arguments here dashboard.get('pages', 'user').set('settings', 'something'); // get accepts an array here dashboard.get(['pages', 'user']).set('settings', 'something'); // no reason why get can't also accept dotted parameters // note: you don't have to call set(), could directly add the property dashboard.get('pages.user').settings = 'something'; 

更新

由于get方法通常返回一个对象,并且不知道您是否需要数组或其他类型的对象,因此您必须指定自己:

 dashboard.get('pages.user').settings = []; 

然后你可以将项目推送到设置数组

 dashboard.get('pages.user').settings.push('something'); dashboard.get('pages.user').settings.push('something else'); 

要实际让get函数从给定的字符串(如pages.user)构造对象层次结构,您必须将字符串拆分为多个部分并检查每个嵌套对象是否存在。 以下是get的修改版本:

 Object.prototype.get = function(prop) { var parts = prop.split('.'); var obj = this; for(var i = 0; i < parts.length; i++) { var p = parts[i]; if(obj[p] === undefined) { obj[p] = {}; } obj = obj[p]; } return obj; } // example use var user = dashboard.get('pages.user'); user.settings = []; user.settings.push('something'); user.settings.push('else'); console.log(dashboard); // {pages: {user: {settings: ["something", "else"] }}} // can also add to settings directly dashboard.get('pages.user.settings').push('etc'); 

我会用三元运算符来做:

 dashboard['pages'][page] = dashboard['pages'][page] ? dashboard['pages'][page] : {}; 

无论是否设置/ null或其他什么,这都可以解决问题。

我不认为有一个很好的内置方法来做到这一点,但你总是可以用一个函数来抽象它。

 function getProperty(obj,prop){ if( typeof( obj[prop] ) == 'undefined' ){ obj[prop] = {}; } return obj[prop]; } 

然后你用

getProperty(dashboard,'pages')['pagename']

要么

 getProperty(getProperty(dashboard,'pages'),'pagename'); 

如上所述,$ .extend将减轻这种负担。

 var foo = dashboard['pages'] || {}; foo['pagename'] = 'your thing here'; dashboard['pages'] = foo; 

解释:第一行将检查第一个值是null,undefined还是… false(不要认为这是一个问题):如果是,创建一个新对象,如果不是,将使用它。

$ .extend是要走的路

 function elem(a,b){ var r={'pages':{'pagename':{}}}; r.pages.pagename[a]={'show':b}; return r; } data={}; //inside the event handler or something: data = $.extend(true,data,elem($(this).closest('li').attr("id"),$(this).is(":hidden") ? 'collapsed' : 'expanded')); 

但老实说 – 无论如何,存储这些信息是一个相当混乱的想法。 我敢打赌,如果你以后需要这些信息,可以使用一个好的选择器或jQuery.data()来完成

好吧,我想你需要这个:

 var dashBoard = new Array(); if(!dashboard['page123']) { dashBoard.push('page123'); } else { ...do what you want } 

好像你在处理XML。

我的案例的最佳解决方案是做一个Object原型

  /** * OBJECT GET * Used to get an object property securely * @param object * @param property * @returns {*} */ Object.get = function(object, property) { var properties = property.split('.'); for (var i = 0; i < properties.length; i++) { if (object && object[properties[i]]) { object = object[properties[i]]; } else { return null; } } return object; }; 

然后你可以得到这样的财产

 var object = {step1:{step2:{step3:'test'}}} Object.get(object, 'step1.step2.step3'); // return 'test' 

希望能帮助到你 :)