Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected output from Object.assign

So I got a little surprised by:

Object.assign({}, Math)

Which returned an empty object. I was doing this to set up my own math module, that I could extend with my own custom functionality, so I thought it would be convenient to do:

Object.assign({}, Math, { 
  sqrt: <my-sqrt-implementation>, 
  add: <my-add-implementation >,
})

But I was surprised to find that the math entries were not included, why is that? In my console I get:

Object.assign({}, Math)
> {}

What went wrong, and how can this be fixed?

like image 942
user2662833 Avatar asked Jan 27 '23 07:01

user2662833


2 Answers

The properties of Math are not enumerable. Object.assign will copy only enumerable and own properties:

The Object.assign() method only copies enumerable and own properties from a source object to a target object. It uses [[Get]] on the source and [[Set]] on the target, so it will invoke getters and setters. Therefore it assigns properties versus just copying or defining new properties. This may make it unsuitable for merging new properties into a prototype if the merge sources contain getters. For copying property definitions, including their enumerability, into prototypes Object.getOwnPropertyDescriptor() and Object.defineProperty() should be used instead.

Thus you should follow the suggestion, and use Object.getOwnPropertyNames(Math) to get a list of own property names, then Object.defineProperty() to assign them:

const props = Object.getOwnPropertyNames(Math)
const myMath = {}
props.forEach(prop => {
    Object.defineProperty(myMath, prop, Object.getOwnPropertyDescriptor(Math, prop))
})

myMath.sin(3.14)  // 0.00159265...

Of course, it is probably better to use prototypical inheritance (Object.create) here. I provide this code because it more closely matches the behavior of Object.assign, i.e. assignment.

like image 170
Fengyang Wang Avatar answered Jan 31 '23 22:01

Fengyang Wang


From : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

The Object.assign() method only copies enumerable and own properties from a source object to a target object

Math properties aren't enumerable or own.

Example:

enter image description here

How can this be fixed?

Use Object.create e.g.

var MyMath = Object.create(Math);
MyMath.sqrt = function () {
};
like image 25
basarat Avatar answered Jan 31 '23 23:01

basarat