代码之家  ›  专栏  ›  技术社区  ›  mcgrailm

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

  •  13
  • mcgrailm  · 技术社区  · 14 年前

    假设我想这样做:

      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 如前所述,这将是一条路,只是不确定如何工作。我得好好想想。

    7 回复  |  直到 6 年前
        1
  •  15
  •   Anurag    14 年前

    在上定义get和set方法 Object . 实际上它可以定义在 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 once:

    // 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)构造对象层次结构,必须将字符串拆分为多个部分,并检查每个嵌套对象是否存在。以下是的修改版本 得到 那就是:

    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');
    
        2
  •  2
  •   arnorhs    14 年前

    我要用三元运算符:

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

    不管它是set/null还是其他什么,这都能做到。

        3
  •  1
  •   Stefan Kendall    14 年前

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

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

    然后你使用

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

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

    如前所述,$.extend将使这一点不那么麻烦。

        4
  •  0
  •   wtaniguchi    14 年前
    var foo = dashboard['pages'] || {};
    foo['pagename'] = 'your thing here';
    dashboard['pages'] = foo;
    

    说明:第一行将检查第一个值是否为空、未定义或…False(不要认为这是一个问题):如果是,创建一个新对象,如果不是,将使用它。

        5
  •  0
  •   naugtur    14 年前

    $.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()来完成。

        6
  •  0
  •   Jundiaius    14 年前

    我想你需要这个:

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

    似乎你在处理XML。

        7
  •  0
  •   Sparw    7 年前

    对我来说最好的解决方案是做一个对象原型

     /**
     * 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'
    

    希望有帮助:)