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

时间:2010-03-26 18:58:33

标签: javascript jquery arrays 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所述将是不确定如何运作的方式。得到我的头脑。

8 个答案:

答案 0 :(得分:15)

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 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');

答案 1 :(得分:2)

我会用三元运算符来做:

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

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

答案 2 :(得分:1)

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

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

然后你使用

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

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

如前所述,$ .extend会减轻这种负担。

答案 3 :(得分:1)

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

 /**
 * 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: ['value1', 'value2'] }}}
Object.get(object, 'step1.step2.step3'); // ['value1', 'value2']
Object.get(object, 'step1.step2.step3.0'); // 'value1'
Object.get(object, 'step1.step2.step3.step4'); // null

希望有所帮助:)

答案 4 :(得分:0)

$ .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()

来完成

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

嗯,我想你需要这个:

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

似乎你正在处理XML。

答案 7 :(得分:0)

如果使用下划线> = 1.9.0,则可以使用propertypropertyOf

PDO::exec(): MySQL server has gone away