Is it possible to destructure onto an existing object? (Javascript ES6) - javascript

For example if I have two objects:
var foo = {
x: "bar",
y: "baz"
}
and
var oof = {}
and I wanted to transfer the x and y values from foo to oof. Is there a way to do that using the es6 destructuring syntax?
perhaps something like:
oof{x,y} = foo

While ugly and a bit repetitive, you can do
({x: oof.x, y: oof.y} = foo);
which will read the two values of the foo object, and write them to their respective locations on the oof object.
Personally I'd still rather read
oof.x = foo.x;
oof.y = foo.y;
or
['x', 'y'].forEach(prop => oof[prop] = foo[prop]);
though.

IMO this is the easiest way to accomplish what you're looking for:
let { prop1, prop2, prop3 } = someObject;
let data = { prop1, prop2, prop3 };
// data === { prop1: someObject.prop1, ... }
Basically, destructure into variables and then use the initializer shorthand to make a new object. No need for Object.assign
I think this is the most readable way, anyways. You can hereby select the exact props out of someObject that you want. If you have an existing object you just want to merge the props into, do something like this:
let { prop1, prop2, prop3 } = someObject;
let data = Object.assign(otherObject, { prop1, prop2, prop3 });
// Makes a new copy, or...
Object.assign(otherObject, { prop1, prop2, prop3 });
// Merges into otherObject
Another, arguably cleaner, way to write it is:
let { prop1, prop2, prop3 } = someObject;
let newObject = { prop1, prop2, prop3 };
// Merges your selected props into otherObject
Object.assign(otherObject, newObject);
I use this for POST requests a lot where I only need a few pieces of discrete data. But, I agree there should be a one liner for doing this.
EDIT: P.S. -
I recently learned you can use ultra destructuring in the first step to pull nested values out of complex objects! For instance...
let { prop1,
prop2: { somethingDeeper },
prop3: {
nested1: {
nested2
}
} = someObject;
let data = { prop1, somethingDeeper, nested2 };
Plus, you could use spread operator instead of Object.assign when making a new object:
const { prop1, prop2, prop3 } = someObject;
let finalObject = {...otherObject, prop1, prop2, prop3 };
Or...
const { prop1, prop2, prop3 } = someObject;
const intermediateObject = { prop1, prop2, prop3 };
const finalObject = {...otherObject, ...intermediateObject };

No, destructuring does not support member expressions in shorthands but only plain propertynames at the current time. There have been talks about such on esdiscuss, but no proposals will make it into ES6.
You might be able to use Object.assign however - if you don't need all own properties, you still can do
var foo = …,
oof = {};
{
let {x, y} = foo;
Object.assign(oof, {x, y})
}

Other than Object.assign there is the object spread syntax which is a Stage 2 proposal for ECMAScript.
var foo = {
x: "bar",
y: "baz"
}
var oof = { z: "z" }
oof = {...oof, ...foo }
console.log(oof)
/* result
{
"x": "bar",
"y": "baz",
"z": "z"
}
*/
But to use this feature you need to use stage-2 or transform-object-rest-spread plugin for babel. Here is a demo on babel with stage-2

BabelJS plugin
If you are using BabelJS you can now activate my plugin babel-plugin-transform-object-from-destructuring (see npm package for installation and usage).
I had the same issue described in this thread and for me it was very exhausting when you create an object from a destructuring expression, especially when you have to rename, add or remove a property. With this plugin maintaining such scenarios gets much more easier for you.
Object example
let myObject = {
test1: "stringTest1",
test2: "stringTest2",
test3: "stringTest3"
};
let { test1, test3 } = myObject,
myTest = { test1, test3 };
can be written as:
let myTest = { test1, test3 } = myObject;
Array example
let myArray = ["stringTest1", "stringTest2", "stringTest3"];
let [ test1, , test3 ] = myArray,
myTest = [ test1, test3 ];
can be written as:
let myTest = [ test1, , test3 ] = myArray;

It's totally possible. Just not in one statement.
var foo = {
x: "bar",
y: "baz"
};
var oof = {};
({x: oof.x, y: oof.y} = foo); // {x: "bar", y: "baz"}
(Do note the parenthesis around the statement.)
But keep in mind legibility is more important than code-golfing :).
Source: http://exploringjs.com/es6/ch_destructuring.html#sec_assignment-targets

You can just use restructuring for that like this:
const foo = {x:"a", y:"b"};
const {...oof} = foo; // {x:"a", y:"b"}
Or merge both objects if oof has values:
const foo = {x:"a", y:"b"};
let oof = {z:"c"}
oof = Object.assign({}, oof, foo)

You can return the destructured object in an arrow function, and use Object.assign() to assign it to a variable.
const foo = {
x: "bar",
y: "baz"
}
const oof = Object.assign({}, () => ({ x, y } = foo));

You can destruct an object assigning directly to another object attribute.
Working example:
let user = {};
[user.name, user.username] = "Stack Overflow".split(' ');
document.write(`
1st attr: ${user.name} <br />
2nd attr: ${user.username}`);
You can work with destructing using variables with the same name of object attribute you want to catch, this way you don't need to do:
let user = { name: 'Mike' }
let { name: name } = user;
Use this way:
let user = { name: 'Mike' }
let { name } = user;
The same way you can set new values to object structures if they have the same attribute name.
Look this working example:
// The object to be destructed
let options = {
title: "Menu",
width: 100,
height: 200
};
// Destructing
let {width: w, height: h, title} = options;
// Feedback
document.write(title + "<br />"); // Menu
document.write(w + "<br />"); // 100
document.write(h); // 200

Try
var a = {a1:1, a2: 2, a3: 3};
var b = {b1:1, b2: 2, b3: 3};
const newVar = (() => ({a1, a2, b1, b2})).bind({...a, ...b});
const val = newVar();
console.log({...val});
// print: Object { a1: 1, a2: 2, b1: 1, b2: 2 }
or
console.log({...(() => ({a1, a2, b1, b2})).bind({...a, ...b})()});

I came up with this method:
exports.pick = function pick(src, props, dest={}) {
return Object.keys(props).reduce((d,p) => {
if(typeof props[p] === 'string') {
d[props[p]] = src[p];
} else if(props[p]) {
d[p] = src[p];
}
return d;
},dest);
};
Which you can use like this:
let cbEvents = util.pick(this.props.events, {onFocus:1,onBlur:1,onCheck:'onChange'});
let wrapEvents = util.pick(this.props.events, {onMouseEnter:1,onMouseLeave:1});
i.e., you can pick which properties you want out and put them into a new object. Unlike _.pick you can also rename them at the same time.
If you want to copy the props onto an existing object, just set the dest arg.

This is kind of cheating, but you can do something like this...
const originalObject = {
hello: 'nurse',
meaningOfLife: 42,
your: 'mom',
};
const partialObject = (({ hello, your }) => {
return { hello, your };
})(originalObject);
console.log(partialObject); // ​​​​​{ hello: 'nurse', your: 'mom' }​​​​​
In practice, I think you'd rarely want to use that though. The following is MUCH more clear... but not nearly as fun.
const partialObject = {
hello: originalObject.hello,
your: originalObject.your,
};
Another completely different route, which includes mucking with the prototype (careful now...):
if (!Object.prototype.pluck) {
Object.prototype.pluck = function(...props) {
return props.reduce((destObj, prop) => {
destObj[prop] = this[prop];
return destObj;
}, {});
}
}
const originalObject = {
hello: 'nurse',
meaningOfLife: 42,
your: 'mom',
};
const partialObject2 = originalObject.pluck('hello', 'your');
console.log(partialObject2); // { hello: 'nurse', your: 'mom' }

This is the most readable and shortest solution I could come up with:
let props = {
isValidDate: 'yes',
badProp: 'no!',
};
let { isValidDate } = props;
let newProps = { isValidDate };
console.log(newProps);
It will output { isValidDate: 'yes' }
It would be nice to some day be able to say something like let newProps = ({ isValidDate } = props) but unfortunately it is not something ES6 supports.

You can use JSON class methods to achieve it as follows
const foo = {
x: "bar",
y: "baz"
};
const oof = JSON.parse(JSON.stringify(foo, ['x','y']));
// output -> {x: "bar", y: "baz"}
Pass properties that need to be added to the resulting object as second argument to stringify function in an array format.
MDN Doc for JSON.stringify

This works in chrome 53.0.2785.89
let foo = {
x: "bar",
y: "baz"
};
let oof = {x, y} = foo;
console.log(`oof: ${JSON.stringify(oof)}`);
//prints oof: { "x": "bar", "y": "baz"}

It's not a beautiful way, nor I recommend it, but it's possible this way, just for knowledge.
const myObject = {
name: 'foo',
surname: 'bar',
year: 2018
};
const newObject = ['name', 'surname'].reduce(
(prev, curr) => (prev[curr] = myObject[curr], prev),
{},
);
console.log(JSON.stringify(newObject)); // {"name":"foo","surname":"bar"}

Related

What is the most elegant way to remove an array of properties from an object immutably in JavaScript?

Not sure if I'm trying to accomplish too much here in an elegant way, but let's say I have an object as follows:
const obj = { foo: 'bar', prop: 'str', hi: 'hello' };
And then I have an array of properties I want to remove from that object:
const keys = ['prop', 'hi'];
I'm looking for the best way I can immutably get an output of:
{ foo: 'bar' }
I was looking into using destructuring assignments but I couldn't figure out how to make it work with an array of properties unless it has a static length:
({ [keys[0]]: value, [keys[1]]: value, ...output }) = o;
Maybe there's an alternative way to do the above line but using mapping?
Thanks!
You could iterate the array and use delete to delete each matching keys.
To make a copy of the object you have you could use the spread operator
const keys = ['prop', 'hi'];
const obj = { foo: 'bar', prop: 'str', hi: 'hello' };
const newobj={...obj}
keys.forEach(o=> delete newobj[o])
console.log(obj)
console.log(newobj)
Here is another approach using Object.fromEntries and filter, some
const keys = ['prop', 'hi'];
const obj = { foo: 'bar', prop: 'str', hi: 'hello' };
res=Object.fromEntries(Object.entries(obj).filter(o=>!keys.some(k=>o[0]==k)))
console.log(res)
console.log(obj)
I would use a combination of the Object.fromEntries, Object.entries, and the Array .filter methods. Then this operation becomes quite straightforward:
function removeKeysFromObj(obj, keys) {
return Object.fromEntries(Object.entries(obj).filter(([key]) => !keys.includes(key)));
}
const obj = { foo: 'bar', prop: 'str', hi: 'hello' };
const keys = ['prop', 'hi'];
const newObj = removeKeysFromObj(obj, keys);
console.log("New object:", newObj);
// And note the original is unmodified:
console.log("Original object:", obj);
One way to approach this is to think in the reverse way: map over the keys in the original object and keep the ones not in the list:
function removeKeys(obj, keys) {
return Object.keys(obj)
.filter(k => !keys.includes(k))
.reduce((newObj, k) => {
newObj[k] = obj[k];
return newObj
}, {});
I'd do it like this.
const obj = { foo: 'bar', prop: 'str', hi: 'hello' };
const keys = ['prop', 'hi'];
let result = Object.keys(obj).reduce((current, item) => (keys.includes(item) || (current[item] = obj[item]), current), {});
console.log(result);

What does 3 dots actually do here

I saw a react component that has the state showed below:
class MyComp extends BaseComponent {
constructor(props) {
super(props);
this.state = {
selectedColumns: [],
params: {
offset: 0,
sort_by: {}
}
}
...
}
}
Then this react component has a method getValue below. Inside this method allParams object is created by using spread syntax. I.e. it is spreading methods argument params, and after that updates params object in components state.
getValue(params){
const allParams = {
...this.state.params,
...params
}
this.setState((prevState) => {
return {
...prevState,
params: allParams
}
})
...
}
It is then called like below in a child component inside MyComp:
goNext() {
const offset = 15 // IT IS NOT JSON, it is a value 15.
this.props.getValue({
offset
})
}
I see that setState is ok but is allParams creation correct? Must not the params be an object (json) to be used with ...? Am i missing something?
In other cases the spread syntax is used like this:
const ob1 = {foo: 123};
const ob2 = {bar: 234};
const merged = {...ob1, ...ob2};
console.log(merged) //Output: { foo: 123, bar: 234 }
But in my case it would be:
const ob1 = {foo: 123};
const ob2 = 15;
const merged = {...ob1, ...ob2};
console.log(merged) //Output: { foo: 123}, and ob2 is not assigned!
The ES6 spread operator can be used on Objects to 'spread' their values into another object to create a clone of that object. It is similar in concept to using Object.assign
Sample
const x = { a : 1 };
const y = {...x}; // y = {a:1} Equivalent to : const y = Object.assign({},x);
const z = {...x , b: 2} // z = {a:1,b:2} Equivalent to Object.assign({a:1},{b:2})
const w = {...x , a: 2} // w = {a:2} Equivalent to Object.assign({a:1},{a:2})
const p = {a:2, ...x} // p={a:1} Equivalent to using Object.assign({a:2},{a:1})
Handy link explaining this in the context of Redux
EDIT: Based on discussion in comments:
In your goNext method, when this happens:
this.props.getValue({
offset
})
You are actually creating an object like this {offset:15}. So when this is used in getValue like:
const allParams = {
...this.state.params,
...params
}
You are essentially overriding the old offset value with 15 and creating a new object. So essentially, we are NOT spreading over 15 but over {offset:15}

Multiple key names, same pair value

I'm trying to setup an object literal in a JavaScript script that has a key with multiple names. referring to the same object value i.e. something like these that I have already tried:
var holidays: {
"thanksgiving day", "thanksgiving", "t-day": {
someValue : "foo"
}
}
var holidays: {
["thanksgiving day", "thanksgiving", "t-day"]: {
someValue : "foo"
}
}
Is there a way I can accomplish this?
Another approach is to do some postprocessing
function expand(obj) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; ++i) {
var key = keys[i],
subkeys = key.split(/,\s?/),
target = obj[key];
delete obj[key];
subkeys.forEach(function(key) { obj[key] = target; })
}
return obj;
}
var holidays = expand({
"thanksgiving day, thanksgiving, t-day": {
someValue : "foo"
}
});
JSON does not offer such a feature, nor do Javascript object literals.
You might be able to make do with something like this:
holidays = {
thanksgiving: {foo: 'foo'},
groundhogDay: {foo: 'bar'},
aliases: {
'thanksgiving day': 'thanksgiving',
't-day': 'thanksgiving',
'Bill Murrays nightmare': 'groundhogDay'
}
}
and then you can check
holidays[name] || holidays[holidays.aliases[name]]
for your data.
It's not a wonderful solution. But it wouldn't be too difficult to write a little function that created this sort of object out of a representation like:
[
{
names: ['thanksgiving', 'thanksgiving day', 't-day'],
obj: {foo: 'foo'}
},
{
names: ['groundhogDay', 'Bill Murrays nightmare'],
obj: {foo: 'bar'}
},
]
if that would be easier to maintain.
Another solution, if you can afford RegExp execution, and ES6 Proxy:
let align = new Proxy({
'start|top|left': -1,
'middle|center': 0,
'end|bottom|right': 1,
}, {
get: function(target, property, receiver) {
for (let k in target)
if (new RegExp(k).test(property))
return target[k]
return null
}
})
align.start // -1
align.top // -1
align.left // -1
align.middle // 0
align.center // 0
align.end // 1
align.bottom // 1
align.right // 1
See MDN Proxy
2021 EDIT:
Another (cleaner?) solution using reduce & defineProperty :
const myDict = [
// list of pairs [value, keys],
// note that a key should appear only once
[-1, ['start', 'left', 'top']],
[0, ['center', 'middle']],
[1, ['end', 'right', 'bottom']],
].reduce((obj, [value, keys]) => {
for (const key of keys) {
Object.defineProperty(obj, key, { value })
}
return obj
}, {})
I guess you could do something like this:
var holidays = {
'thanksgiving day': {
foo: 'foo'
}
};
holidays.thanksgiving = holidays['t-day'] = holidays['thanksgiving day'];
If you see yourself doing this often or you have more values consider this pattern:
'thanksgiving, t-day, thanks, thank, thank u'.split(',').forEach(function(key) {
holidays[key] = holidays['thanksgiving day'];
});
A better approach would be to process your data beforehand instead of adding duplicates.
That should work as expected:
function getItem(_key) {
items = [{
item: 'a',
keys: ['xyz','foo']
},{
item: 'b',
keys: ['xwt','bar']
}];
_filtered = items.filter(function(item) {
return item.keys.indexOf(_key) != -1
}).map(function(item) {
return item.item;
});
return !!_filtered.length ? _filtered[0] : false;
}
With ES6 you could do it like this, but it's not ideal:
const holidays = {
"single": {
singleValue: "foo",
},
...([
"thanksgiving day", "thanksgiving", "t-day",
].reduce((a, v) => ({...a, [v]: {
someValue: "foo",
}}), {})),
"other": {
otherValue: "foo",
},
};
I still think the cleanest solution is probably:
let holidays = {
"t-day": {
someValue: "foo",
},
};
holidays["thanksgiving"] = holidays["t-day"];
holidays["thanksgiving day"] = holidays["t-day"];
Now this may be overkill for you, but here's a generic function that will create an object with "multiple keys." What it actually does is have one real property with the actual value, and then defines getters and setters to forward operations from the virtual keys to the actual property.
function multiKey(keyGroups) {
let obj = {};
let props = {};
for (let keyGroup of keyGroups) {
let masterKey = keyGroup[0];
let prop = {
configurable: true,
enumerable: false,
get() {
return obj[masterKey];
},
set(value) {
obj[masterKey] = value;
}
};
obj[masterKey] = undefined;
for (let i = 1; i < keyGroup.length; ++i) {
if (keyGroup.hasOwnProperty(i)) {
props[keyGroup[i]] = prop;
}
}
}
return Object.defineProperties(obj, props);
}
This is less sketchy than you would expect, has basically no performance penalty once the object is created, and behaves nicely with enumeration (for...in loops) and membership testing (in operator). Here's some example usage:
let test = multiKey([
['north', 'up'],
['south', 'down'],
['east', 'left'],
['west', 'right']
]);
test.north = 42;
test.down = 123;
test.up; // returns 42
test.south; // returns 123
let count = 0;
for (let key in test) {
count += 1;
}
count === 4; // true; only unique (un-linked) properties are looped over
Taken from my Gist, which you may fork.
Same reponse (ES6 Proxy, RegExp), but in a shorter way (and significantly less legible)
let align = new Proxy({
'start|top|left': -1,
'middle|center': 0,
'end|bottom|right': 1,
}, { get: (t, p) => Object.keys(t).reduce((r, v) => r !== undefined ? r : (new RegExp(v).test(p) ? t[v] : undefined), undefined) })
align.start // -1
align.top // -1
align.left // -1
align.middle // 0
align.center // 0
align.end // 1
align.bottom // 1
align.right // 1
//create some objects(!) you want to have aliases for..like tags
var {learn,image,programming} =
["learn", "image", "programming"].map(tag=>({toString:()=>tag }));
//create arbitrary many aliases using a Map
var alias = new Map();
alias.set("photo", image);
alias.set("pic", image);
alias.set("learning", learn);
alias.set("coding", programming);
//best put the original tagNames in here too..
//pretty easy huh?
// returns the image object
alias.get("pic");
// ;)
here is a way you can initialize an object with several keys sharing the same value
var holidays = {
...["thanksgiving day", "thanksgiving", "t-day"].reduce((acc, key) => ({ ...acc, [key]: 'foo' }), {})
}
although I would personally think it was more clear if it was written out
Object.fromEntries produces some fairly readable and concise code:
var holidays = Object.fromEntries(
["thanksgiving day", "thanksgiving", "t-day"].map(k => [k, "foo"]));
The spread syntax can be used to include this alongside other key/value pairs:
var holidaysAndMore = {
"A": "a",
...Object.fromEntries(
["thanksgiving day", "thanksgiving", "t-day"].map(k => [k, "foo"])),
"B": "b"
};

Can one set multiple properties inside an object literal to the same value?

For example, can I do this?:
{
a: b: c: d: 1,
e: 2,
geh: function() { alert("Hi!") }
}
EDIT:
Is there some way I can avoid doing this?:
{
a: 1,
b: 1,
c: 1,
d: 1,
e: 2,
geh: function() { alert("Hi!") }
}
An update to this (in terms of the latest JavaScript abilities) avoiding unwanted defined vars:
{
let v;
var obj = {
"a": (v = 'some value'),
"b": v,
"c": v
};
}
This will mean v won't be defined outside the block, but obj will be.
Original answer
Another way of doing the same thing is:
var v;
var obj = {
"a": (v = 'some value'),
"b": v,
"c": v
};
You could set a line of equality between various properties:
var foo = {};
foo.a = foo.b = foo.c = "Hello";
Or you could just create a method that does the mass-assignment for you:
var foo = {
setValue: function( props, value ) {
while ( props.length ) this[ props.pop() ] = value;
}
}
foo.setValue( [ "a", "b", "c" ] , "Foo" );
You could try this. It's not the syntactic sugar you're looking for (eg. {a,b,c:1, d:2}) but it's another way to do it, although all of these answers are pretty much fine.
(object,fields,value)=>Object.assign(object||{}, ...fields.map(f=>({[f]:value}) ))
Explanation:
(object,fields,value)=>
Takes an object (or falsey value if you want a new object, feel free to rearrange the argument order)
Object.assign(object||{},
Will return an object based on object and it will mutate the object. To disable this, simply add a first argument object literal like this Object.assign({}, object || {}, ...
...fields.map(f=>({[f]:value}) )
Will spread the array of fields mapped to objects as a list of extra arguments to Object.assign. ['a','b'].map(f=>({[f]:value}) ) will give [{a:value}, {b:value}] and f(...[{a:1},{b:1}]) is like f({a:1},{b:1}). Object.assign does the rest :)
There's yet another approach: using a mapping function...
// This will be standard!
if (!Object.fromEntries)
Object.fromEntries = entries => entries.reduce ((o, [key, value]) => ({
...o,
[key]: value
}), {})
const setSameValue = (source, props, value) => ({
...source,
...Object.fromEntries (
props.map (prop => [prop, value])
)
})
// The important part: do what you want with ease!
const output = setSameValue ({}, ['1', '01'], 'string 1')
const obj = { x: 1, y: 'hello' }
const output2 = setSameValue (obj, ['1', '01'], 'string1')
console.log ('output1:', output)
console.log ('output2:', output2)
You could wrap in a closure too, if you didn't want multiple local vars. This syntax seems to be popular (but ugly):
var obj = (function() { var v='some value'; return { a:v, b:v, c:v }; })();
Use for of loop instead.
for (let [key, value] of Object.entries(object_name)) {
object_name[key] = 0; // the value that you want to assign
}
Or yet another way:
{...['a', 'b', 'c', 'd'].reduce((obj,prop)=>({...obj, [prop]: 1}), {}) }
It can be wrapped up pretty neatly by extending the Array prototype:
Array.prototype.ditto = function(v) { return this.reduce((o,p)=>({...o, [p]: v}), {}) }
So now it can be used like this:
{
...['a', 'b', 'c', 'd'].ditto(1),
...['e', 'f'].ditto(2)
geh: function() { alert("Hi!") }
}
Explanation: the .reduce starts off with an empty object {} and for each element prop return an object which is whatever was in the object already ...obj plus a new property with our value 1: [prop]: 1. Then expand these properties into the outer object with the ... at the start.
If you had tons of properties reduce wouldn't be the most efficient, but you could change it to:
Array.prototype.ditto = function(v) { let o = {}; this.forEach(p => o[p] = v); return o; }
More readable and more efficient but less cool??

Is there any way to use a numeric type as an object key?

It seems that when I use a numeric type as a key name in an object, it always gets converted to a string. Is there anyway to actually get it to store as a numeric? The normal typecasting does not seem to work.
Example:
var userId = 1;
console.log( typeof userId ); // number
myObject[userId] = 'a value';
console.dir(myObject);
Dir Output:
{
'1': 'a value'
}
What I want is this:
{
1: 'a value'
}
Advice?
No, this is not possible. The key will always be converted to a string. See Property Accessor docs
Property names must be strings. This means that non-string objects cannot be used as keys in the object. Any non-string object, including a number, is typecasted into a string via the toString method.
> var foo = {}
undefined
> foo[23213] = 'swag'
'swag'
> foo
{ '23213': 'swag' }
> typeof(Object.keys(foo)[0])
'string'
In an object, no, but I have found Map extremely useful for this application. Here is where I have used it for numeric keys, a key-based event.
onKeydown(e) {
const { toggleSidebar, next, previous } = this.props;
const keyMapping = new Map([
[ 83, toggleSidebar ], // user presses the s button
[ 37, next ], // user presses the right arrow
[ 39, previous ] // user presses the left arrow
]);
if (keyMapping.has(e.which)) {
e.preventDefault();
keyMapping.get(e.which)();
}
}
Appears to be by design in ECMA-262-5:
The Property Identifier type is used to associate a property name with a Property Descriptor. Values of the Property Identifier type are pairs of the form (name, descriptor), where name is a String and descriptor is a Property Descriptor value.
However, I don't see a definite specification for it in ECMA-262-3.
Regardless, I wouldn't attempt to use non-strings as property names.
you can use, Map if you want different datatype as keys
const map1 = new Map();
map1.set(1,3)
map1.set('1','string')
// expected output: 3
console.log(map1.get(1)) //output 3;
console.log(map1.get('1')) //output 'string';
Here is the solution. Please tell me the environmental setups if this is not working
const screens = {
"768": "large",
"200": "small"
}
const keys = Object.keys(screens).map(key => parseInt(key))
// OR Number(key)
console.log(keys) // Output [200, 768]
Do we need something like this?
var userId = 1;var myObject ={};
console.log( typeof userId ); // number
myObject[userId] = 'a value';
console.dir(myObject);
Console:
Object
1
:
"a value"
You can't, but you can always convert keys to a numbers
const data = { 15: "value", name: "Apple" };
const result = Object.keys(data) // get keys as an array
.map((item) => {
return parseInt(item); // convert to integer number
})
.filter((item) => !isNaN(item)); // remove non number elements
console.log(result); //Output: [15]
const a = {
'1': 'a value'
}
//by using a + before any string value it will convert(parse) that into a number
const b = Object.key(a);
console.log(+b); //parse
console.log(typeof b); //number
Per Mozilla:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax[Spread syntax]1
let obj1 = { foo: 'bar', x: 42 };
let obj2 = { foo: 'baz', y: 13 };
const merge = ( ...objects ) => ( { ...objects } );
let mergedObj1 = merge (obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }
let mergedObj2 = merge ({}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
Just order the items before hand and you should get the result you want.
So for your case:
const merge = (...objects) => ({...objects});
//An object with numeric keys
const values = ["a value", "another value", "and another value"];
let merged = merge(...values);
console.log(merged);
You can try this:
arr = {}
function f(a,b,c) {
arr = arguments
}
f("*","#","_")
console.log(arr)
//returns Object { 0: "*", 1: "#", 2: "_" }```
In JavaScript, numerical strings and numbers are interchangeable, so
myObject[1] == myObject['1']
If you really want number to be the key for an object, you might want an array (i.e. created with new Array() or []).

Categories

Resources