admin管理员组文章数量:1178539
let say I want to do this:
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';
});
}
I get an error saying:
Dashboard.pages is undefined
Is there away to dynamically add pages
and the children that follow without having to do the work of checking to see if it is defined first then if it's not doing:
dashboard['pages'] = {};
because sometimes they may already exist and I don't want to have to inspect the tree first I just want to build the branches as needed
EDIT
I changed pagename
to page
to show that page names will change and also I want to point out that the pages could really be anything too.
The idea is that you have any object that can contain objects with parameters without checking to see if the branches exist
It looks like $extend
as stated will be the way to go just not sure how that works. Got to get my head around that.
let say I want to do this:
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';
});
}
I get an error saying:
Dashboard.pages is undefined
Is there away to dynamically add pages
and the children that follow without having to do the work of checking to see if it is defined first then if it's not doing:
dashboard['pages'] = {};
because sometimes they may already exist and I don't want to have to inspect the tree first I just want to build the branches as needed
EDIT
I changed pagename
to page
to show that page names will change and also I want to point out that the pages could really be anything too.
The idea is that you have any object that can contain objects with parameters without checking to see if the branches exist
It looks like $extend
as stated will be the way to go just not sure how that works. Got to get my head around that.
- sorry - the script makes no sense to me. The use of bracket indexers implies the desire to dynamically index the object, but you are using constants. That, combined with the statement that you 'do not want to do the work' has me wondering if you know what you are trying to accomplish. Not trying to denigrate - just an observation as to why you may not get the answer you are looking for. – Sky Sanders Commented Mar 26, 2010 at 19:14
- 1 Better solution for ES6 here. stackoverflow.com/a/52471690/10405671 – pool Commented Sep 24, 2018 at 1:28
9 Answers
Reset to default 14Define get and set methods on an Object
. Actually it could be defined just on the dashboard
object and only its descendants, but that's easy to do.
Object.prototype.get = function(prop) {
this[prop] = this[prop] || {};
return this[prop];
};
Object.prototype.set = function(prop, value) {
this[prop] = value;
}
Iterate through nested properties using this get()
method and call set()
whenever a value has to be 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"}}};
You could also extend/modify the get
method to accept the nested properties as individual arguments or an array or a string. Using that, you'd only have to call 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';
Update:
Since the get method generically returns an object and does not know whether you need an array or some other type of object, so you would have to specify that yourselves:
dashboard.get('pages.user').settings = [];
Then you could push items to the settings array as
dashboard.get('pages.user').settings.push('something');
dashboard.get('pages.user').settings.push('something else');
To actually have the get function construct the object hierarchy from a given string such as pages.user, you would have to split the string into parts and check if each nested object exists. Here is a modified version of get
that does just that:
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');
I would do it with the ternary operator:
dashboard['pages'][page] = dashboard['pages'][page] ? dashboard['pages'][page] : {};
That will do the trick no matter if it's set/null or whatever.
I don't think there's a good builtin way to do this, but you could always abstract it with a function.
function getProperty(obj,prop){
if( typeof( obj[prop] ) == 'undefined' ){
obj[prop] = {};
}
return obj[prop];
}
Then you use
getProperty(dashboard,'pages')['pagename']
or
getProperty(getProperty(dashboard,'pages'),'pagename');
As mentioned, $.extend will make this less burdensome.
The best solution for my case was to do a Object prototype
/**
* 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;
};
And then you can get your property like this
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
Hope it helps :)
var foo = dashboard['pages'] || {};
foo['pagename'] = 'your thing here';
dashboard['pages'] = foo;
Explaining: the first line will check if the first value is null, undefined or... false (don't think this is a problem here): if it is, create a new object, if it is not, will use it.
$.extend is the way to go
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'));
But honestly - this is a rather messy idea to store this information anyway. I bet that if You need that information later it could be done with a good selector or with jQuery.data()
Well I guess you need this:
var dashBoard = new Array();
if(!dashboard['page123']) {
dashBoard.push('page123');
} else {
...do what you want
}
Seems you are dealing with XML.
If you use underscore >= 1.9.0, you can use property
and propertyOf
:
d={a: {b: "c"}}
_.property(["a", "b", "c", "e"])(d) // undefined
_.property(["a", "b"])(d) // "c"
_.propertyOf(d)(["a", "b", "c", "e"]) // undefined
_.propertyOf(d)(["a", "b"]) // "c"
This method from my tiny object utility library answer the question asked by @mcgrailm in his comment of the marked answer: Question dashboard.get('pages.user.settings').push("something"); dashboard.get('pages.user.settings').push("somethingelse") Answer
const users = {
0:{
name:"John",
age:30,
car:null,
job: "Developer",
address: "Dakar",
interest: {
music: ["rnb", "rap"],
sports: ["football", "basketball"],
food: [
{
senegal: {0:"yassa", 1:"mafé"},
mali: ["yassa", "mafé", "jolof rice"]
},
{
usa: ["burger", "nuggets",
[
{jfr:["jfr_sn", "jfr_ng"]}
]
]
},
{
italia: ["pizza", "peperoni"]
}
]
}
},
1:{
name:"Jane",
age:20,
car:null,
job: "attorney",
address: "Dakar",
interest: {
music: ["rnb", "rap"],
sports: ["football", "basketball"],
language: ["deutch", "english"]
}
},
2:{
name:"Moussa",
age:26,
car:null,
job: "plice officer",
address: "Dakar",
interest: {
music: ["rnb", "rap", "trap"],
sports: ["basketball", "handball"],
countries: {
Africa: ["Senegal", "Rwanda", "Morroco"],
Europe: ["England", "Russia"],
Asia: ["China", "Saudi Arabia", "Palestine"],
America: ["Brasil", "Mexico", "USA"],
Oceania: ["Australia"]
}
}
}
}
/*In this example we are using our users object declared previously and we are tryin to access the jfr key
by using the path that leads to this key
*/
//using vanilla js
let result1 = users[0].interest.food[1].usa[2][0].jfr
//using this library
let result2 = _Object(users).getEntryByPath("0.interest.food.1.usa.2.0.jfr")
//expected output for both method
[ "jfr_sn", "jfr_ng" ]
more utility visit https://www.npmjs.com/package/spicy_object
本文标签: javascriptadding to json property that may or may not exist yetStack Overflow
版权声明:本文标题:javascript - adding to json property that may or may not exist yet - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738065402a2057836.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论