how to object value to its on property object ?
I tried like this
var obj = {
a:2,
b:this.a
}
Then try obj.b it is giving undefined ..can I make function in object?
Expected output 2
const obj = {
a: 2,
get b() {
return this.a;
}
};
console.log(obj.b);
const obj2 = {
a: 2,
b: function() {
return this.a;
}
};
console.log(obj2.b());
See it in action: https://jsfiddle.net/rqnbxw86/
Related
is this expected?
const testObj = {
a: 'hi',
b: 'there'
}
function destructured_test({a, b}) {
a = 'bye';
}
console.log(testObj);
destructured_test(testObj);
console.log(testObj);
function test(t) {
t.a = 'bye';
}
console.log(testObj);
test(testObj);
console.log(testObj);
only the function 'test' mutates testObj 'destructured_test' seems to be copying the properties over instead of preserving the reference
I am trying to change only the value of copied object, not the main but both objects change as of the result of running this code.
const Randomdata = {
a: 10,
b: 5,
c: {
f: "value1",
q: "value2"
}
};
function copy(MainObj) {
let ObjCopy = {};
for (let key in MainObj) {
ObjCopy[key] = MainObj[key];
}
return ObjCopy;
}
const newObj = copy(Randomdata);
Randomdata.c.q = "value3";
console.log(newObj);
console.log(Randomdata);
Though JSON.parse and JSON.stringify will work , but you will need a recusive function if want to achieve the same result using for..in. The reason is value of key c is a object and when you are copying it, it is just referencing to the old copy
const Randomdata = {
a: 10,
b: 5,
c: {
f: "value1",
q: "value2"
}
};
function copy(MainObj, ObjCopy) {
for (let key in MainObj) {
// check if the value is a object , if so then
// reclusively call the same function
if (typeof MainObj[key] === 'object') {
copy(MainObj[key], ObjCopy)
} else {
ObjCopy[key] = MainObj[key];
}
}
return ObjCopy;
}
const newObj = copy(Randomdata, {});
Randomdata.c.q = "value3";
console.log(newObj);
console.log(Randomdata);
I use Object.defineProperty method to define a property of an object:
const o = { a: 1 }
Object.defineProperty(o, 'b', {
get() {
return this.a
}, set(value) {
this.a = value
}
})
However, when I am using console.log try to print object o, the b property seem not in it.
But when I try to use o.b to access to it, it can return correct value
So I am confused: why the property can't be printed but can be accessed?
Properties added with .defineProperty() are by default non-enumerable.
Make them "visible" by setting enumerable: true
var foo = {}
Object.defineProperty(foo, "a", {
get() { return "a"; }
});
Object.defineProperty(foo, "b", {
get() { return "b"; },
enumerable: true
});
console.log(Object.keys(foo));
Well, you have own enumerable properties and all own properties of an object.
To get all enumerable own properties, you could take Object.keys and for getting the non-enumerable properties as well, you coul take Object.getOwnPropertyNames.
Maybe console.log shows only the enumerable properties of an object. This implementation is up to the vendor.
const o = { a: 1 }
Object.defineProperty(o, 'b', {
get() {
return this.a
}, set(value) {
this.a = value
}
})
console.log(o);
console.log(Object.keys(o));
console.log(Object.getOwnPropertyNames(o));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can get propertyNames using Object.getOwnPropertyNames
const o = { a: 1 }
Object.defineProperty(o, 'b', {
get() {
return this.a
}, set(value) {
this.a = value
}
})
console.log(Object.getOwnPropertyNames(o))
Consider a function returns an nested object and I want to modify the property inside the nested object.
In the below example, I'm calling the function many times or I need to store it in a temporary variable. Is there a way to invoke only once inside the braces and spread/modify inside the same object many times.
const getObject = () => {
return {
a: {
b: {
c: 1,
d: 2,
}
},
e: 3
}
}
var modifiedD = {
...getObject(),
a: {
b: {
...getObject().a.b,
d: 4
}
}
}
console.log(modifiedD);
when declaring a key after ...getObject() it replace the whole value. It does not merge the inner object behind a.
So you could do it as you have done and call getObject() multiple time.
An other solution could be to handle it using a function of your own merging the objects, like :
function mergeObjects(obj1, obj2) {
// We are going to copy the value of each obj2 key into obj1
Object.keys(obj2).forEach((x) => {
// If we have an object, we go deeper
if (typeof obj2[x] === 'object') {
if (obj1[x] === void 0) {
obj1[x] = {};
}
mergeObjects(obj1[x], obj2[x]);
} else {
obj1[x] = obj2[x];
}
});
return obj1;
}
const getObject = () => {
return {
a: {
b: {
c: 1,
d: 2,
}
},
e: 3
}
}
const modifiedD = mergeObjects(getObject(), {
a: {
b: {
d: 4,
},
},
});
console.log(modifiedD);
WARNING, the function I have made mutate the object which may not be the best answer
Or call it only once and then set the keys one by one like :
const getObject = () => {
return {
a: {
b: {
c: 1,
d: 2,
}
},
e: 3
}
}
const modifiedD = getObject();
modifiedD.a.b.d = 4;
console.log(modifiedD);
Further to my previous answer, as Grégory NEUT pointed out you could have a lot larger complexity.
If so, you could simply create two objects and then merge them. I found a function code snippet to be able to do that using Object.assign
Example:
const getObject = () => {
return {
a: {
b: {
c: 1,
d: 2,
}
},
e: 3
}
}
var modifiedD = getObject();
var newD = {
a: {
b: {
d: 4
},
y: 1
},
z: 20
}
/** TAKEN FROM https://gist.github.com/ahtcx/0cd94e62691f539160b32ecda18af3d6 **/
// Merge a `source` object to a `target` recursively
const merge = (target, source) => {
// Iterate through `source` properties and if an `Object` set property to merge of `target` and `source` properties
for (let key of Object.keys(source)) {
if (source[key] instanceof Object) Object.assign(source[key], merge(target[key], source[key]))
}
// Join `target` and modified `source`
Object.assign(target || {}, source)
return target
}
modifiedD = merge(modifiedD, newD);
console.log(modifiedD);
You can try the following:
getParentObj(path, obj) {
return path.split('.').reduce((o,i)=>o[i], obj);
}
const parent = getParentObj('a.b', getObject());
parent[d] = 24;
Consider the following code:
const obj = {
a: 'foo',
b: function () { return this.a }
}
console.log(obj.a) // 'foo'
console.log(obj.b()) // 'foo'
const { a, b } = obj
console.log(a) // 'foo'
console.log(b()) // undefined
When I destruct obj, b() cannot access a anymore.
How can I preserve obj scope and allow b() to access it's siblings properties/methods while descructuring?
#dayan-moreno-leon posted a good option.
But I just noticed that I can be handled simply by using always static calls:
const obj = {
a: 'foo',
b: function () { return obj.a } //HERE! :D
}
const { a, b } = obj
console.log(obj.a) // 'foo'
console.log(obj.b()) // 'foo'
console.log(a) // 'foo'
console.log(b()) // 'foo'