JavaScript - Exporting a harcoded array vs creating one - javascript

Let's say I have a file data.js, which contains an array of some data that will be imported somewhere (eg. a React component).
EXAMPLE A:
const DATA = [
{
firstName: 'jim',
lastName: 'beam',
fullName: 'jim beam'
},
{
firstName: 'jack',
lastName: 'daniels',
fullName: 'jack daniels'
}
];
export default DATA;
Ok, cool. Thing is, we're writing out the fullName property, which could be gathered by combining firstName and lastName. This is a very trivial example for clarity, so bear with me. We could also do something like this:
EXAMPLE B:
const DATA = [
{ firstName: 'jim', lastName: 'beam' },
{ firstName: 'jack', lastName: 'daniels' }
];
export default DATA.map(person => ({
...person,
fullName: `${person.firstName} ${person.lastName}`
});
Heck, we could even do this!
EXAMPLE C:
const DATA = ['jim beam', 'jack daniels'];
export default DATA.map(person => {
const [firstName, lastName] = person.split(' ');
return {
firstName,
lastName,
fullName: person
};
};
So, imagine you have a huuge list of data, where multiple values could be derived from one initial value. My question is how would examples B and C differ from just hardcoding everything right off the bat like example A?
If you had hundreds of items, examples B and C could have much less overhead, a smaller file size, and can reduce potential typos... But, we're declaring an array and then exporting a different one, which I assume could have a performance dip? Thoughts?

How about a class with a getter that evaluates fullName on access?
It offers smaller in-memory size, and doesn't have a performance issue because fullName property of each datum is not computed until they are imported, and accessed.
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
get fullName() {
return `${this.firstName} ${this.lastName}`
}
}
let a = new Person('Charles', 'Martel');
console.log(a.fullName)
// expected result: "Charles Martel"
Your data can then be declared as the following.
const DATA = [
new Person('jim', 'beam'),
new Person('jack','daniels')
];

Related

Should I deep copy when modifying nested object?

I recently started learning functional programming in Javascript, and one thing that's valued is Immutability. One way to preserve immutability is to when we want to modify some object that we first create a copy and then modify that copy and return it, for example:
const person = {
firstName: 'John',
lastName: 'Smith',
}
const modifyFName = obj => {
const objCopy = {...obj};
objCopy.firstName = 'James';
return objCopy;
}
console.log(modifyFName(person)) // {firstName: 'James', lastName: 'Smith'}
console.log(person) // {firstName: 'John', lastName: 'Smith'}
But if I want to modify some deeply nested object creating shallow copy like one above wouldn't make much of a difference, for example:
const person = {
firstName: 'John',
lastName: 'Smith',
parents: {
mom: {
firstName: 'Jennifer',
lastName: "Swift"
},
dad: {
firstName: 'Tom',
lastName: 'Cartman'
}
}
}
const modifyDadName = obj => {
const objCopy = {...obj};
objCopy.parents.dad.firstName = 'Aurelion';
return objCopy;
}
console.log(modifyDadName(person)) // {... dad: "Aurelion"}
console.log(person) // {... dad: "Aurelion"}
Both objects have changed. So I am wondering in this situation should I perhaps use deep copy, or maybe use some third-party Immutable data structures, or is there some other solution for this?
You're right that a shallow copy doesn't help, but you don't need a full deep copy, you only have to make copies of the things you want to change. In your case, that's person, parents, and dad, but not mom:
const modifyDadName = obj => {
return { // Replacement `obj` (`person`)
...obj,
parents: { // Replacement `obj.parents`
...obj.parents,
dad: { // Replacement `obj.parents.dad`
...obj.parents.dad,
firstName: "Aurelion", // New name
}
}
};
};
dad changes because, well, that's the operation we're doing (changing firstName). :-) parents changes because changing dad means there's a new object on its dad property. person (obj) changes because there's a new parents object. But mom doesn't change, so we can reuse the same object.

Refactoring a destructuring into an object destructuring

I am refactoring my code, which involves converting a big list of let statements into an object called personDetails:
personDetails = {
firstName: '',
lastName: '',
zipcode: 'xyz',
age: 20,
gender: 'm'
}
Currently, I am destructuring the values returned from my array like this:
[firstName, lastName] = getNames(zipcode, age, gender)
This works fine. But now that I am switching to an object, how do I update that object with the returned values? I will be passing in the object as an argument like this:
getNames(personDetails)
Do I have to do something like this?
personDetails = getNames(personDetails)
The called function might look something like this (abbreviated):
const getNames(personDetails) => {
personDetails.firstname = 'Jack'
personDetails.lastName = 'Jones'
}
1) Your arrow function had a typo, you must declare it with an = before the argument, like this:
const getNames = (personDetails) => { // Correct
const getNames(personDetails) => { // Incorrect
2) Inside your function, you weren't modifying an object key, but creating a new one instead. Remember that objects keys differs if you use upper or lowercase letters, firstName and firstname are not the same key.
3) Last, when you create an argument in your function, do not declare it with the same name of the global object, since it could create unexpected results. Then, you don´t need to destructure your object, just return the complete object.
let personDetails = { // Using let
firstName: '',
lastName: '',
zipcode: 'xyz',
age: 20,
gender: 'm'
};
const getNames = (obj) => { // obj is the argument
obj.firstName = 'Jack';
obj.lastName = 'Jones';
return obj; // Return complete object
}
personDetails = getNames(personDetails);
console.log(personDetails);
If you want to destructure the object, you can do it too the same way you do it with the array, but I wouldn´t recommend it because it makes the code less clear:
const personDetails = { // Using const
firstName: '',
lastName: '',
zipcode: 'xyz',
age: 20,
gender: 'm'
};
const getNames = (obj) => { // obj is the argument
obj.firstName = 'Jack';
obj.lastName = 'Jones';
return [obj.firstName, obj.lastName]; // Return part of object as an array
}
[personDetails.firstName, personDetails.lastName] = getNames(personDetails);
console.log(personDetails);

How to store an objects in array after method in my class

Please see my code below.
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
addUser() {
users.push(this.name, this.email)
}
}
const userOne = new User ('John', 'john#mail.com');
const userTwo = new User ("Alan", "alan#mail.com");
let users = [];
userOne.addUser();
userTwo.addUser();
After method addUser i have array with names and emails but i would like to have an array with objects as below
users = [
{ name: 'John', email: 'john#mail.com' }
{ name: 'Alan', email: 'alan#mail.com' }
]
How my method addUser should looks in my prototype and if variable users is in correct place or can be store somewhere in Class?
Thanks in advance
You're pushing the object properties one after the other, rather than as an object together.
Try this for your addUser method:
addUser() {
users.push({name: this.name, email: this.email})
}
You just need to push each proprieties
users.push({name: this.name, email: this.email})
If you want to do this automatically you can use:
users.push(Object.assign({}, this))
Or you cloud just pass the whole object:
users.push(this)
Anyhow, I would suggest not to use users globally.

Destructure object and assign to another object in one line [duplicate]

This question already has answers here:
Is it possible to destructure onto an existing object? (Javascript ES6)
(16 answers)
Closed 2 years ago.
Is there a way to do the following in one line?
let person = {}
const { firstName, lastName } = getNames()
//or this
//const { firstName, lastName } = await getNames()
person.firstName = firstName
person.lastName = lastName
I often do this when coding, and hoping there is a shortcut. I can not see any hints on how to do this on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment.
I was trying something like the below however, it overrides the other properties in the object.
let person = { age: 20 }
person = { ...getNames() }
I don't think this will work well with async/await functions either, as they return a promise.
let person = { age: 20 }
person = { ...await getNames() }
You could probably try something like this:
({firstName: person.fistName, lastName: person.lastName} = getNames());
You would need person defined as an object beforehand.
You can use Object.assign for this.. For example.
let person = { firstName: 'John', lastName: 'Doe', age: 67, //etc... }
let newPerson = Object.assign(person, getNames())
console.log(newPerson)
// Expected output: `{ firstName: 'newFirstName', lastName: 'newLastName', age: 67, etc... }`
You can view more on Object.assign here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

How to populate an array in javascript if I want to have multiple elements for a single index of an array

How to populate an array in javascript when I want to store multiple elements in a single index?
I want to populate an array in Javascript. What I am trying to do is to store both firstName and lastName of a person in an array index. I am trying to do person[0].firstName = 'Dilshadur'; and then person[0].secondName = 'Rahman'; but It's not working and I think this is not the correct syntax to do so.
person[0].firstName.fill('Md Dilshadur Rahman');
person[0].lastName = 'Rahman';
person[1].firstName = 'Tabassum Monia';
person[1].lastName = 'Disha';
I am getting in the console something like this: "Uncaught TypeError: Cannot read property 'firstName'", I think this because of the wrong syntax and I am not being able to find the correct syntax.
You would have to have an object assigned to each index of the array, and each of those objects would have the firstName and lastName properties.
Ex:
let person = [];
person[0] = {firstName: 'Dilshadur', lastName: 'Rahman'};
person[1] = {firstName: 'Tabassum Monia', lastName: 'Disha'};
You should consider creating a separate class or something where this structure is defined.
class Person {
constructor(first, last) {
this.firstName = first;
this.lastName = last;
}
}
let person = [];
person[0] = new Person('Dilshadur', 'Rahman');
person[1] = new Person('Tabassum Monia', 'Disha');
You need to store an array of objects in that case.
const results = [
{ firstName: 'clark', lastName: 'kent' },
{ firstName: 'bruce', lastName: 'wayne' }
]
You can then use the spread operator to populate the entire index.
const newResults = [
{ firstName: 'peter', lastName: 'parker' },
...results
]
You can also push to your array, however it is good practice to not mutate your data and instead create an updated copy of it.
You can create array of objects
person = [];
person[0] = { firstName: "abc" , lastName: "def" } :
Or you can push values to it by
person.push( { firstName: "abc" , lastName: "def" } )

Categories

Resources