I have this variable:
var a = {b:1, c:2, d:'rawr', rawr:10};
I want to destructure these into the local scope so I do:
var {b, c, d} = a;
This works fine but I need to get rawr out. I tried this:
var {b, c, d, [a.d]} = a;
But this gives me missing : after property id so I tried:
So I then though to do a two step:
var {b, c, d} = a;
var {[d]} = a;
However this gives me SyntaxError: missing : after property id. Is there anyway to do this in ES6?
Expected result is that:
var b = 1;
var c = 2;
var d = 'rawr';
var rawr = 10;
You can destructure it like this:
var {b, c, d, [d]: q} = a;
So then whatever was in a property with a name d is assigned to q.
UPD:
What you asked in the update is not possible.*
You need to give it a variable to assign to. You cannot use "computed" variable names1, as that would go against the rules of static scope resolution for identifiers. So you should do
var {b, c, d, [a.d]: rawr} = a;
to get the value of the a.d-named property in the rawr variable.
1: Well, you can use eval or a with statement in sloppy mode to do this, but both are despised exactly because of this.
You could use Object.keys(), Function.prototype.bind() though caveat is that value of variable is within an array; have not yet determined how to return only variable.
var a = {
b: 1,
c: 2,
d: 'rawr',
rawr: 10
};
function de(val, key) {
var [val] = window[val] = [a[val]];
}
Object.keys(a).forEach(de.bind(this));
console.log(b, c, d, rawr);
jsfiddle https://jsfiddle.net/ravkgzjb/2/
Related
The question I have is best given by way of this jsfiddle, the code for which is below:
var a = 1, b = 'x', c = true;
var d = {a: a, b: b, c: c}; // <--- object literal
var e = [a, b, c]; // <--- array
var f = {a, b, c}; // <--- what exactly is this??
// these all give the same output:
alert(d.a + ', ' + d.b + ', ' + d.c );
alert(e[0] + ', ' + e[1] + ', ' + e[2]);
alert(f.a + ', ' + f.b + ', ' + f.c );
What sort of a data structure is f? Is it just a shorthand for d?
var f = {a, b, c};
It came with ES6 (ECMAScript 2015) and means exactly the same as:
var f = {a: a, b: b, c: c};
It is called Object Literal Property Value Shorthands (or simply property value shorthand, shorthand properties).
You can also combine shorthands with classical initialization:
var f = {a: 1, b, c};
For more information see Property definitions in Object initializer.
It is an Object Initializer Property Shorthand in ES6.
var f = {a, b, c, d:1}; // Will be equal to {a:a, b:b, c:c, d:1}
This works because the property value has the same name as the property identifier. This a new addition to the syntax of Object Initialiser (section 11.1.5) in the latest ECMAScript 6 draft Rev 13. And of course, just like the limitations set from ECMAScript 3, you can’t use a reserved word as your property name.
Such a shorthand won’t dramatically change your code, it only makes everything a little bit sweeter!
function createCar(name, brand, speed) {
return { type: 'Car', name: name, brand: brand, speed: speed };
}
// With the new shorthand form
function createSweetCar(name, brand, speed) {
return { type: 'Car', name, brand, speed }; // Yes it looks sweet.
}
Please see the compatibility table for support for these notations. In non-supporting environments, these notations will lead to syntax errors.
This shorthand notation offers object matching pretty nicely:
In ECMAScript5 what we used to do:
var tmp = getData();
var op = tmp.op;
var lhs = tmp.lhs;
var rhs = tmp.rhs;
Can be done in ECMAScript6 with a single line of code:
var { op, lhs, rhs } = getData();
var f = {a, b, c}; // <--- what exactly is this??
It defines an object in JavaScript using the new ECMAScript 2015 notation:
As per Mozilla Developer Network:
"Objects can be initialized using new Object(), Object.create(), or using the literal notation (initializer notation). An object initializer is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({})."
var a = "foo",
b = 42,
c = {};
// Shorthand property names (ES6)
var o = { a, b, c };
is equivalent to:
var a = "foo",
b = 42,
c = {};
var o = {
a: a,
b: b,
c: c
};
I am not sure about best practice that how to deal with it:
const obj = {a: null}
function getObject(){
// I may return a, or anything that could be nested property
return obj.a
}
let v = getObject()
v = 'updated'
console.log(obj.a) // null
I expect a value co-operates with v assignment. I have seen with operator but people say avoid using it. So, what should I be using?
If a function returns the value of a field/variable then you get a reference to the object stored in that field/variable, not a reference to the variable itself. You either need to have getObject() return an object, which you then set the field value on, like so:
function getObject(){
return obj;
}
getObject().a = 'something';
Or you need to write a function that assigns the field value instead, like so:
function setValue(val) {
obj.a = val;
}
Another option would be to wrap your values in objects, so getObject never returns null, instead returning an empty object on which you set a field value, like so:
const obj = {a: {}}
function getObject(){
return obj.a
}
let v = getObject();
v.value = "foo";
// obj now equals {a: {value: "foo"}}
As written you're returning the value currently stored in a, saving that to a variable, then changing the value in the new variable. The value in obj remains unchanged.
You can access any Javascript object using dot like what you had in getObject , also you can set value to the object like this anyObject.key = value this will change the value of the key in the object.
const obj = new Object({ a : null })
Object.prototype.setA = function(a) {
this.a = a
}
obj.setA('hello world!')
console.log(obj)
If you want to update a global object values you need to access the object and assign it
const obj = {a: null}
function getObject(){
return obj.a
}
let v = getObject()
console.log(getObject()) //null
console.log(obj.a) // null
obj.a = "a" //you are now overriding what was null here
console.log(obj.a) //contains "a" now or whatever type you want it to be
I'd recommend you check this helpful tutorial: https://www.w3schools.com/js/js_objects.asp
Understanding JS variables is important:
let a = 1;
console.log(a); //1
a = 2;//overrides a
console.log(a); //2
What you are trying to achieve is not very clear but I would recommend to always mutate the global var to avoid errors and confusion.
Short answer:
you are changing the value of v and not changing the object referenced by v
Long answer:
If this was written in a class-based langauge (like C, java, or C++, etc.), this would also not change a. Because you are only changing what v points or reference to (in case of pointers).
In C :
void *v = (void*) &getObject() // v is equal to obj (or points to obj) obj
v = (void*) &some.thing.something() // v is now equal to some.thing.something() or points to some.thing.something()
// obj has not changed
print(obj.a) // null which is reasonable
// printf ("%s", obj.a); is the correct syntax in C
To actually change a you need to change the value of of the address in memory that is referenced by v
In C:
void *v = (void*) &getObject()
*v = (void *) some.thing.something()
print(obj.a) // now obj is equal to 'some.thing.something()'
// printf ("%s", obj.a); is the correct syntax in C
Now in your code why a is not changing ?
When it comes to Javascript, it is a langauge based on prototypes, rather than class-based
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model
Check the link above.
It is because of the same reason explained in the first C code above. You are just changing the value of v and not changing the object referenced by v
let v = getObject()
v = 'some.thing.something()'
console.log(obj.a) // null
As far as I know, the arrays and objects always act as pointers and just point to somewhere a memory location.
In the following example, as var a is updated, so as b pointing to same memory location as a, should also be updated and final answer should be true, true.
Why is it not happening??? At what instance of time, b gets a different pointer than a and why???
Example:
var a = [2,3,5];
var b = a;
a = [33,45];
console.log(a,b);
console.log(a==b,a===b);
However, to support my clause kindly look at following unchanged values example. Here I am sure both a and b point to same memory location containing data as [2,3,5]. They got same values and are always equated as true.
var a = [2,3,5];
var b = a;
console.log(a==b,a===b);
Because you are not updating the reference of the new object [33, 45].
Following code might help you understand better.
a = [{'a': 1}, {'b': 2}];
b = a;
console.log(a, b);
// creates new object and assigns to the same variable
b = b.concat ([{'c': 3}]);
console.log(a, b);
// but property of object is still referenced in by a and b
b[0].a = 100;
console.log(a,b);
a[2].c = 100; // throws exception, because 'a' does not have the reference to object which refers the object created in 'b'
console.log(a,b);
look at blow:
var a = [2,3,5];
var b = a;
and after the a = [33,45];
the pointer is point to a new obj, not the obj changed
My code:
var a = "1",
b = "hello",
c = { "100" : "some important data" },
d = {};
d[a]["greeting"] = b;
d[a]["data"] = c;
console.debug (d);
I get the following error:
Uncaught TypeError: Cannot set property 'greeting' of undefined.
I'm trying to do something similar to an associative array. Why isn't this working?
you never set d[a] to any value.
Because of this, d[a] evaluates to undefined, and you can't set properties on undefined.
If you add d[a] = {} right after d = {} things should work as expected.
Alternatively, you could use an object initializer:
d[a] = {
greetings: b,
data: c
};
Or you could set all the properties of d in an anonymous function instance:
d = new function () {
this[a] = {
greetings: b,
data: c
};
};
If you're in an environment that supports ES2015 features, you can use computed property names:
d = {
[a]: {
greetings: b,
data: c
}
};
You have to set d[a] to either an associative array, or an object:
d[a] = [];
d[a] = {};
Without setting, this is what's happening:
d[a] == undefined, so you're doing undefined['greeting']=b; and by definition, undefined has no properties. Thus, the error you received.
The object stored at d[a] has not been set to anything. Thus, d[a] evaluates to undefined. You can't assign a property to undefined :). You need to assign an object or array to d[a]:
d[a] = [];
d[a]["greeting"] = b;
console.debug(d);
In ES6 you can use the spread operator, if d[a] is undefined it will just ignore, but if it has content it will keep it
d[a] = { ...d[a], greeting: b, data: c };
The accepted answer will override anything in d, which is not the behaviour we would always want
In javascript almost everything is an object, null and undefined are exception.
Instances of Array is an object. so you can set property of an array, for the same reason,you can't set property of a undefined, because its NOT an object
i'd just do a simple check to see if d[a] exists and if not initialize it...
var a = "1",
b = "hello",
c = { "100" : "some important data" },
d = {};
if (d[a] === undefined) {
d[a] = {}
};
d[a]["greeting"] = b;
d[a]["data"] = c;
console.debug (d);
d = {} is an empty object right now.
And d[a] is also an empty object.
It does not have any key values. So you should initialize the key values to this.
d[a] = {
greetings:'',
data:''
}
This occurs due to setting value to an object property without properly defining it's structure.
eg: The following code will give such error, because we are assigning value to an array. That can't be possible.
let boatNames = [];
boats.map(boat => {
while( i < boats.length){
boatNames[i].name = boat.boat.name;
i++;
}
})
To make it work, before setting some value to a property (boatNames[i].name = boat.boat.name;) make sure you define it first. like this... boatNames[i] = {};
My code:
var a = "1",
b = "hello",
c = { "100" : "some important data" },
d = {};
d[a]["greeting"] = b;
d[a]["data"] = c;
console.debug (d);
I get the following error:
Uncaught TypeError: Cannot set property 'greeting' of undefined.
I'm trying to do something similar to an associative array. Why isn't this working?
you never set d[a] to any value.
Because of this, d[a] evaluates to undefined, and you can't set properties on undefined.
If you add d[a] = {} right after d = {} things should work as expected.
Alternatively, you could use an object initializer:
d[a] = {
greetings: b,
data: c
};
Or you could set all the properties of d in an anonymous function instance:
d = new function () {
this[a] = {
greetings: b,
data: c
};
};
If you're in an environment that supports ES2015 features, you can use computed property names:
d = {
[a]: {
greetings: b,
data: c
}
};
You have to set d[a] to either an associative array, or an object:
d[a] = [];
d[a] = {};
Without setting, this is what's happening:
d[a] == undefined, so you're doing undefined['greeting']=b; and by definition, undefined has no properties. Thus, the error you received.
The object stored at d[a] has not been set to anything. Thus, d[a] evaluates to undefined. You can't assign a property to undefined :). You need to assign an object or array to d[a]:
d[a] = [];
d[a]["greeting"] = b;
console.debug(d);
In ES6 you can use the spread operator, if d[a] is undefined it will just ignore, but if it has content it will keep it
d[a] = { ...d[a], greeting: b, data: c };
The accepted answer will override anything in d, which is not the behaviour we would always want
In javascript almost everything is an object, null and undefined are exception.
Instances of Array is an object. so you can set property of an array, for the same reason,you can't set property of a undefined, because its NOT an object
i'd just do a simple check to see if d[a] exists and if not initialize it...
var a = "1",
b = "hello",
c = { "100" : "some important data" },
d = {};
if (d[a] === undefined) {
d[a] = {}
};
d[a]["greeting"] = b;
d[a]["data"] = c;
console.debug (d);
d = {} is an empty object right now.
And d[a] is also an empty object.
It does not have any key values. So you should initialize the key values to this.
d[a] = {
greetings:'',
data:''
}
This occurs due to setting value to an object property without properly defining it's structure.
eg: The following code will give such error, because we are assigning value to an array. That can't be possible.
let boatNames = [];
boats.map(boat => {
while( i < boats.length){
boatNames[i].name = boat.boat.name;
i++;
}
})
To make it work, before setting some value to a property (boatNames[i].name = boat.boat.name;) make sure you define it first. like this... boatNames[i] = {};