const person = { name: 'John', age: 28 } const newPerson = person newPerson.age = 30 console.log(newPerson === person) // console.log(person) // { name: 'John', age: 30 }
newObj
, we automatically change the old variable obj
. All because they refer to the same object. In most cases, this behavior is undesirable, and writing code like this is bad. Let's see how you can solve this problem. const person = { name: 'John', age: 28 } const newPerson = Object.assign({}, person, { age: 30 }) console.log(newPerson === person) // console.log(person) // { name: 'John', age: 28 } console.log(newPerson) // { name: 'John', age: 30 }
Object.assign
is an ES6 feature that allows you to take objects as parameters. It combines all the objects passed to it with the first. You may have wondered: why is the first parameter an empty object {}
? If the 'person'
parameter was the first to go, we would still change the person
. If we had written { age: 30 }
, then we would again overwrite 30 with the value 28, since it would have gone later. Our solution works - the person has remained unchanged, since we dealt with it as unchanged! const person = { name: 'John', age: 28 } const newPerson = { ...person, age: 30 } console.log(newPerson === person) // console.log(newPerson) // { name: 'John', age: 30 }
'spread' (...)
operator copies all properties from a person
to a new object. Then we define the new property 'age'
, which overwrites the old one. Observe the order: if age: 30
were defined above a person
, then it would be overwritten by age: 28
. const person = { name: 'John', password: '123', age: 28 } const newPerson = Object.keys(person).reduce((obj, key) => { if (key !== property) { return { ...obj, [key]: person[key] } } return obj }, {})
const characters = [ 'Obi-Wan', 'Vader' ] const newCharacters = characters newCharacters.push('Luke') console.log(characters === newCharacters) // :-(
const characters = [ 'Obi-Wan', 'Vader' ] const newCharacters = [ ...characters, 'Luke' ] console.log(characters === newCharacters) // false console.log(characters) // [ 'Obi-Wan', 'Vader' ] console.log(newCharacters) // [ 'Obi-Wan', 'Vader', 'Luke' ]
const characters = [ 'Obi-Wan', 'Vader', 'Luke' ] // const withoutVader = characters.filter(char => char !== 'Vader') console.log(withoutVader) // [ 'Obi-Wan', 'Luke' ] // const backInTime = characters.map(char => char === 'Vader' ? 'Anakin' : char) console.log(backInTime) // [ 'Obi-Wan', 'Anakin', 'Luke' ] // const shoutOut = characters.map(char => char.toUpperCase()) console.log(shoutOut) // [ 'OBI-WAN', 'VADER', 'LUKE' ] // const otherCharacters = [ 'Yoda', 'Finn' ] const moreCharacters = [ ...characters, ...otherCharacters ] console.log(moreCharacters) // [ 'Obi-Wan', 'Vader', 'Luke', 'Yoda', 'Finn' ]
const characters = [ 'Obi-Wan', 'Vader', 'Luke' ] const sortedCharacters = characters.sort() console.log(sortedCharacters === characters) // :-( console.log(characters) // [ 'Luke', 'Obi-Wan', 'Vader' ]
push
and sort
should act exactly like map
, filter
and concat
, return new arrays. But they do not, and if you change something, you can probably break the Internet. If you need sorting, then perhaps you can use slice
to get it all done: const characters = [ 'Obi-Wan', 'Vader', 'Luke' ] const sortedCharacters = characters.slice().sort() console.log(sortedCharacters === characters) // false :-D console.log(sortedCharacters) // [ 'Luke', 'Obi-Wan', 'Vader' ] console.log(characters) // [ 'Obi-Wan', 'Vader', 'Luke' ]
slice()
is a bit of a hack, but it works.Object.observe(object, callback)
pretty heavy. However, if you keep the state unchanged, you can do without oldObject === newObject
and thus check whether the object has changed. Such an operation does not burden the CPU so much.Source: https://habr.com/ru/post/317248/
All Articles