How can an object's property access other property? [duplicate] - javascript

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 8 years ago.
Why can't i do something like this in javascript?
var big = { a:1, b:2, c:3, d:big.a }
How can an object's one property access another?
//--------------------------------edited as below ----------------------------------
Thanks for all the answers, now i found another question:
when i do this:
var big = {
a : 1,
b : 2,
c : 3,
d : this.a
}
console.log(big.d);
It's undefined
However, when i do this:
var big = {
a : 1,
b : 2,
c : 3,
d : function(){console.log(this.a)}
}
big.d();
It logs out 1
I wonder what's going on here, is it because it is a function in the second code somehow makes the 'this' accessible?
Thanks.

you can do this
var big = { a:1, b:2, c:3};
big.d = big.a;
In your code when you are using d:big.a it is still not defined i'e. big is not defined

Try this
var big = new function ()
{
this.a = 1;
this.b = 2;
this.c = 3;
this.d = this.a;
}
alert(big.a);
alert(big.b);
alert(big.c);
alert(big.d);
Hope this helps.

Since the variable big to get big.a hasn't been declared yet when you actually declare big. In this case you should inject the object d afterwards.
var big = { a:1, b:2, c:3 };
big.d = big.a;

You can't do it in the object literal. This is because the right hand side of the = is evaluated before the assignment takes place. Javascript first creates an object with the properties given and then assigns it to the variable. Therefore, at the point when you attempt to access big.a, the assignment has not taken place, so big is undefined and you get an error because you cannot access the properties of undefined.
You need to assign big.d after the assignment:
var big = { a:1, b:2, c:3};
big.d = big.a;

Related

How to use special characters (like hyphen) in destructuring assignment syntax? [duplicate]

This question already has answers here:
How to destructure object properties with key names that are invalid variable names?
(3 answers)
Closed 7 months ago.
I'm curious of why that seems impossible:
const {a, b, 'special-one'} = { a:1, b:2, 'special-one': 3 };
// output => missing : after property id
Will it be possible to find that syntax working in future ES versions ?
Thanks for your lights :)
Rename the variable within the destructure statement, you can't have a variable with a hyphen in it's name. You can rename using the syntax below, see MDN: Assigning to new variable names
A property can be unpacked from an object and assigned to a variable
with a different name than the object property.
const {
a,
b,
'special-one': specialOne
} = {
a: 1,
b: 2,
'special-one': 3
};
console.log(specialOne);
special-one can't be the variable name. So you need another name for that like specialOne. Use : after the key name for new variable name.
const {a, b, 'special-one':specialOne} = { a:1, b:2, 'special-one': 3 };
console.log(specialOne)
In the above case you have a plain string as key name. But if there is an expression you will need to use []
let keyName = 'special-one'
const {a, b, [keyName]:specialOne} = { a:1, b:2, 'special-one': 3 };
console.log(specialOne)

Use object values as new values inside same object [duplicate]

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 8 years ago.
I am trying to do something like this:
var obj = {
a: 5,
b: this.a + 1
}
(instead of 5 there is a function which I don't want to execute twice that returns a number)
I can rewrite it to assign obj.b later from obj.a, but can I do it right away during declaration?
No. this in JavaScript does not work like you think it does. this in this case refers to the global object.
There are only 3 cases in which the value this gets set:
The Function Case
foo();
Here this will refer to the global object.
The Method Case
test.foo();
In this example this will refer to test.
The Constructor Case
new foo();
A function call that's preceded by the new keyword acts as a constructor. Inside the function this will refer to a newly
created Object.
Everywhere else, this refers to the global object.
There are several ways to accomplish this; this is what I would use:
function Obj() {
this.a = 5;
this.b = this.a + 1;
// return this; // commented out because this happens automatically
}
var o = new Obj();
o.b; // === 6
This should return the correct values:
function () {
var aVar = 5;
var bVar = aVar + 1;
return {
a : aVar,
b : bVar;
}
}();
As it turns out you can't reference an object inside another object unless the first one is a function. But you can do it this way.
var obj = {
a: 5
}
obj.b = obj.a + 1; // create field b in runtime and assign it's value
If you console.log(obj) you will have
obj = {
a: 5,
b: 6
}
This way you keep the object literal structure for the remaining part of the code
No, in your example, the value of this doesn't refer to the object literal.
You'll need to assign a value to b after the object has been created in order to base it on another property in obj.
in chrome debugger
> var o = {a: 5, b: this.a+1}
undefined
> o.b
NaN
> o.a
5
No. this will take the same meaning as it would outside the definition.

Is it possible to define a dynamically named property using object literal in JavaScript? [duplicate]

This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 1 year ago.
Consider the following
var a = {foo: "bar"};
Equivalent to
var a = {};
a.foo = "bar";
Equivalent to
var a = {};
a['foo'] = "bar";
Equivalent to
var a = {}
var b = "foo";
a[b] = "bar";
Is it possible to do something like
var b = "foo";
var a = { [b]: "bar" };
Such that the result would be
// => {foo: "bar"}
Acceptable solutions are in JavaScript or CoffeeScript
No.
There is no way to do it using object literal notation.
UPDATE: According to the ECMAScript standard 6.0 you are now able to do the following:
var b = 'foo';
var a = { [b]: 'bar' };
console.log( a.foo ); // "bar"
However, this solution won't work in old browsers, which do not support ES6.
ES6 supports computed properties.
// code from my original question now works in ES6 !
let b = "foo";
let a = { [b]: "bar" };
a.foo; //=> "bar"
Any expression can be used within the [] to define the property name
let a = {
[(xs => xs.join(''))(['f','o','o'])]: 'bar'
};
a.foo; //=> "bar"
If you need to rely on this behavior in an ES5 world, you can lean on the very capable babel.js to transpile your ES6 code to ES5-compatible code.
JSON parse allows you to convert a JSON string into an object:
JSON.parse('{"'+dynamicProperty+'":"bar"}');
This is not exactly an object litteral, but if your objective is to enter your property name as a variable it works.
As others have said, no, there's currently no syntax for interpolated key strings in object literals in CoffeeScript; but it seems at some point this feature existed! In these GitHub issues there's some discussion about it: #786 and #1731.
It's implemented in Coco and LiveScript as:
b = 'foo'
a = {"#{b}": 'baz'}
# Or..
a = {(b): 'bar'}
As of CoffeeScript version 1.9.1 this works:
b = "foo"
a = "#{b}": "bar"
It compiles to:
var a, b, obj;
b = "foo";
a = (
obj = {},
obj["" + b] = "bar",
obj
);
Try it.
JavaScript
var a, b;
(a = {})[b = 'foo'] = 'bar';
CoffeeScript
(a = {})[b = 'foo'] = 'bar'
To answer your question, this is the only way that I know of. It uses eval. But beware, eval is evil!
var b = "foo";
var a = eval('({ ' + b + ': ' + '"bar"' + ' })');
This is an ugly solution. To play it safe you should not rely on this. Don't use it!

How to disable pointers usage in JS?

Why is the result {"a":"b","c":1}?
var foo = {"a":"b","c":0};
var bar = foo;
bar.c++;
alert(JSON.stringify(foo));
How to disable this behavior?
Both foo and bar variables reference the same object. It doesn't matter which reference you use to modify that object.
You cannot disable that behaviour, this is how JavaScript and many other major languages work. All you can do is to clone the object explicitly.
var foo = {"a":"b","c":0};
var bar = {"a":foo.a, "c": foo.c};
bar.c++;
What you're doing is making a second reference to an object but what it seems you want is a copy of that object instead.
If you want that functionality then you really want a copy function that copies all of the properties, one by one, into a new object:
// Take all the properties of 'obj' and copy them to a new object,
// then return that object
function copy(obj) {
var a = {};
for (var x in obj) a[x] = obj[x];
return a;
}
var foo = {"a":"b","c":0};
var bar = copy(foo);
bar.c++;
alert(JSON.stringify(foo));
and you'll get {"a":"b","c":0}
First, Javascript doesn't pass pointers, it passes references, slightly different. Secondly, there's no way to modify Javascript's default behavior, unfortunately fortunately.
What you might want to do is create a constructor and use that to create two similar, but separate instances of an object.
function Foo(a, b) {
this.a = a;
this.b = b;
}
var bar1 = new Foo(0, 0);
var bar2 = new Foo(0, 0);
bar2.b++;
console.log(bar1);
console.log(bar2);
>> {a:0, b:0};
>> {a:0, b:1};
You can't disable the way javascript works.
If you change a reference object, it effects all the object references...

Can I reference other properties during object declaration in JavaScript? [duplicate]

This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 8 years ago.
I am trying to do something like this:
var obj = {
a: 5,
b: this.a + 1
}
(instead of 5 there is a function which I don't want to execute twice that returns a number)
I can rewrite it to assign obj.b later from obj.a, but can I do it right away during declaration?
No. this in JavaScript does not work like you think it does. this in this case refers to the global object.
There are only 3 cases in which the value this gets set:
The Function Case
foo();
Here this will refer to the global object.
The Method Case
test.foo();
In this example this will refer to test.
The Constructor Case
new foo();
A function call that's preceded by the new keyword acts as a constructor. Inside the function this will refer to a newly
created Object.
Everywhere else, this refers to the global object.
There are several ways to accomplish this; this is what I would use:
function Obj() {
this.a = 5;
this.b = this.a + 1;
// return this; // commented out because this happens automatically
}
var o = new Obj();
o.b; // === 6
This should return the correct values:
function () {
var aVar = 5;
var bVar = aVar + 1;
return {
a : aVar,
b : bVar;
}
}();
As it turns out you can't reference an object inside another object unless the first one is a function. But you can do it this way.
var obj = {
a: 5
}
obj.b = obj.a + 1; // create field b in runtime and assign it's value
If you console.log(obj) you will have
obj = {
a: 5,
b: 6
}
This way you keep the object literal structure for the remaining part of the code
No, in your example, the value of this doesn't refer to the object literal.
You'll need to assign a value to b after the object has been created in order to base it on another property in obj.
in chrome debugger
> var o = {a: 5, b: this.a+1}
undefined
> o.b
NaN
> o.a
5
No. this will take the same meaning as it would outside the definition.

Categories

Resources