This question already has answers here:
JavaScript set object key by variable
(8 answers)
Closed 2 years ago.
I am trying to get a static Java-like map object working in Javascript. I am not a javascript expert, but am wondering if this is possible. What I am trying to do is the following:
I am defining
const MY_CONST_1 = 'Constant 1 value';
const MY_CONST_2 = 'Constant 2 value';
and a "map-like" object like this:
const CONST_AMOUNT_MAP = {
MY_CONST_1: 30,
MY_CONST_2: 22
}
Then, in a function I define:
function getAmount(constValue) {
return CONST_AMOUNT_MAP[constValue];
}
My expectation would be that the above function when called with
getAmount('Constant 1 value')
returned the number "30". However,
CONST_AMOUNT_MAP[constValue];
returns "undefined". Only
CONST_AMOUNT_MAP[MY_CONST_1]
returns the correct amount.
Is it possible to define an Object such as CONST_AMOUNT_MAP that allows to lookup entries based on pre-defined const variables rather than based on the actual value of the consts?
Thank you
When you define an object literal, the key names are given literally - they're not evaluated. In other words:
const CONST_AMOUNT_MAP = {
MY_CONST_1: 30,
MY_CONST_2: 22
}
...makes an object with a key named MY_CONST_1, not the value of any variable you've defined with the name MY_CONST_1.
You can achieve what you're after by instead declaring your keys wrapped in [], which will force the enclosed to be evaluated.
const CONST_AMOUNT_MAP = {
[MY_CONST_1]: 30,
[MY_CONST_2]: 22
}
Or
const CONST_AMOUNT_MAP = {};
CONST_AMOUNT_MAP[MY_CONST_1] = 30;
CONST_AMOUNT_MAP[MY_CONST_2] = 22;
Note that the keys, however you add them, must be strings or symbols. Since you mention 'map', be aware that there are true maps in JS, in which the keys can be of any data type.
Related
This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 4 months ago.
const A = 0;
const LOOKUP = { A : "A"};
console.log(LOOKUP[A]);
console.log(LOOKUP[0]);
Result:
undefined
undefined
Second try:
var A = 0;
const LOOKUP = { A : "A"};
console.log(LOOKUP[A]);
console.log(LOOKUP[0]);
Result:
undefined
undefined
How am I supposed to do this then? And can somebody explain why this doesn't work in JavaScript the way one would expect it to work coming from other languages?
The correct way is:
const A = 0;
const LOOKUP = {};
LOOKUP[A] = 'A';
console.log(LOOKUP[A]);
console.log(LOOKUP[0]);
const LOOKUP = { A : "A"};
The left side of the colon means that the key is the string "A". The string part is implicit, since all keys are strings (or symbols). So to access the property, you need to do console.log(LOOKUP.A) or console.log(LOOKUP["A"])
If you want the key to be a computed value, then you need to use square brackets:
const LOOKUP = { [A]: "A" };
That means that we should resolve the variable A, and use its value as the key. That key is the number 0, which then gets coerced into the string "0". You can then look it up by any of console.log(LOOKUP["0"]), console.log(LOOKUP[0]), or console.log(LOOKUP[A])
Looks like you are searching for some enums (typescript):
enum ETest {
A = 1
};
console.log(ETest['A']); // 1
console.log(ETest[1]); // A
Doing LOOKUP[A] is like doing LOOKUP[0] which is undefined.
You should try it as
console.log(LOOKUP["A"])
This has nothing to do with const or var keyword. The way you are trying to access an object property is incorrect.
const A = 0;
const LOOKUP = { A : "A"};
console.log(LOOKUP["A"]); // Correct Approach: Property access through bracket notation should be done using a string (or a variable assigned to a string).
console.log(LOOKUP[0]); // Property `0` doesn't exist on object `LOOKUP`, so it'll return `undefined`.
This question already has answers here:
In JavaScript, how to conditionally add a member to an object?
(29 answers)
Closed 2 years ago.
I'm aware with ES6 JavaScript object you can dynamically declare variables as object keys, using [], for example:
{[2 + 2]: "four!"}
gives the output {"4": "four!"}
the question is, can a similar method be done in order to add an entire property, through variables etc., inline? Meaning, like suppose I have the following test object:
var myObj = {
someProp: 2,
someOtherProp: 3 //only add this prop if a condition is met
}
is there anything I can write in the inline object for someOtherProp, to only have it be added to the object, if a certain condition is met? So for example (pseudocode), something like this
var myObj = {
someProp: 2,
[someBool ? null : "someOtherProp: 3"] //only add this prop if a condition is met
}
would give the ouput (considering someBool is true), like the above, but if someBool is false, it would give me
var myObj = {
someProp: 2
}
??
I'm aware I can simply add a property (or delete one) to (/from) the object later, using the [] indexer, like
someBool && (myObj["someOtherProp"] = 3)
as well as make some kind of helper function for this,
but I was wondering if there was a way to do it using the inline-object notation?
You could spread an object with a conditional operator.
{} is a neutral value.
var myObj = {
someProp: 2,
...(someBool ? {} : { someOtherProp: 3 })
}
This question already has answers here:
Map vs Object in JavaScript
(15 answers)
Closed 2 years ago.
let m = new Map();
let obj = {};
let keyString = 'a string';
let keyObj = {};
let keyFunc = function() {};
obj[keyObj] = 'object inside object as keys!';
obj[keyFunc] = function() {}
m.set(keyObj, 'object');
m.set(keyFunc, 'function');
console.log(typeof obj[keyObj]); // type = string
console.log(typeof obj[keyFunc]); // type = function
console.log(typeof m.get(keyObj)); // type = string
console.log(typeof m.get(keyFunc)); // type = string
console.log(m.get(keyObj)) // object
console.log(m.get(keyFunc)) // function
Then what is difference between map and object?
map also converts the keys type to string.
Map is a data structure which helps in storing the data in the form of pairs. The pair consists of a unique key and a value mapped to the key. It helps prevent duplicity.
Object follows the same concept as that of map i.e. using key-value pair for storing data. But there are slight differences which makes map a better performer in certain situations.
Few basic differences are as follows:
In Object, the data-type of the key-field is restricted to integer,
strings, and symbols. Whereas in Map, the key-field can be of any
data-type (integer, an array, even an object!)
In the Map, the original order of elements is preserved. This is not
true in case of objects.
The Map is an instance of an object but the vice-versa is not true.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
Is there a better way to do the following. consider this code:
this.state = {
dates: [
{date: '1st', matches:[]},
{date: '2nd', matches:[]},
{date: '3rd', matches:[]},
{date: '4th', matches:[]},
{date: '5th', matches:[]}
]
}
addToDates = () => {
let dates = this.state.dates;
const matches = this.props.matches;
matches.forEach(function(match){
dates.forEach(function(date){
if (match.date == date.date){
this.setState({dates: this.state.dates.concat(match)})
}
})
})
}
what i am trying to do is iterate through 2 arrays and if i find a match that has the same date as a date then i want to add it to the matches array.
2 problems, firstly is there a better way to compare 2 arrays rather than iterating through both?
secondly i get cant read setState of undefined even though i have:
this.addToDates = this.addToDates.bind(this) bound it in my constructor. i thought arrow functions solved that scoping too?
You need to use arrow functions in your addToDate method. You don't actually have to bind addToDates in your constructor as you are using an arrow function as a class property.
The value of this when you are using this.setState is different if you don't use an arrow functions for your forEach loops.
addToDates = () => {
let dates = this.state.dates;
const matches = this.props.matches;
matches.forEach(match =>{
dates.forEach(date =>{
if (match.date == date.date){
this.setState({dates: this.state.dates.concat(match)})
}
});
});
As per MDN
Until arrow functions, every new function defined its own this value
(a new object in the case of a constructor, undefined in strict mode
function calls, the base object if the function is called as an
"object method", etc.). This proved to be annoying with an
object-oriented style of programming.
An arrow function does not create its own this, the this value of the
enclosing execution context is used.
This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Closed 7 months ago.
In PHP I can mess around with variable variables and I'm wondering if I can do the same in JavaScript.
I want to create a new object with a property which's name is based on the value of a variable.
if ( obj.name === 'foo' ) {
var data = { foo: value };
}
if ( obj.name === 'bar' ) {
var data = { bar: value };
}
Is there a shorter way of doing this without using eval()? Something like:
var data = { obj.name: value };
Try this:
var data = {};
data[obj.name] = value;
You can read some more about js objects Here.
Objects in JavaScript are simply hash maps. You can access members by indexing with their names. For your problem you can use
var data = {};
data[obj.name] = value;
I've used this to implement a dynamic dispatch mechanism for arithmetic operations on different numerical types as described here.