# Extending Math object through prototype doesn’t work

I try to extend JavaScript `Math`

. But one thing surprised me.

When I tried to extend it by `prototype`

```
Math.prototype.randomBetween = function (a, b) {
return Math.floor(Math.random() * (b - a + 1) + a);
};
```

In console I have error ‘Cannot set property ‘randomBetween’ of undefined’ …

But if I asigne this function to `Math.__proto__`

```
Math.__proto__.randomBetween = function (a, b) {
return Math.floor(Math.random() * (b - a + 1) + a);
};
```

Then everything works fine.

Can anybody explain me why it works in this way? I appreciate any help.

`Math`

isn’t a constructor, so it doesn’t have `prototype`

property:

```
new Math(); // TypeError: Math is not a constructor
```

Instead, just add your method to `Math`

itself as an own property:

```
Math.randomBetween = function (a, b) {
return Math.floor(Math.random() * (b - a + 1) + a);
};
```

Your approach with `__proto__`

works because, since `Math`

is an `Object`

instance, `Math.__proto__`

is `Object.prototype`

.

But then note you are adding `randomBetween`

method to all objects, not only to `Math`

. This can be problematic, for example when iterating objects with a `for...in`

loop.

That’s because there’s `Math`

is an object, *not* a `function`

.

In javascript, a `function`

is the rough equivalent of a class in object oriented languages. `prototype`

is a special property which lets you add instance methods to this class^{1}. When you want to extend that class, you use `prototype`

and it “just works”.

Now let’s think about what `Math`

is. You never create a math object, you just use it’s methods. In fact, it doesn’t make sense to create two different `Math`

objects, because `Math`

always works the same! In other words, the `Math`

object in javascript is just a convenient way to group a bunch of pre-written math related functions together. It’s like a dictionary of common math.

Want to add something to that group? Just add a property to the collection! Here’s two easy ways to do it.

```
Math.randomBetween = function() { ... }
Math["randomBetween"] = function() {... }
```

Using the second way makes it a bit more obvious that it’s a dictionary type collection, but they both do the same thing.

To quote this answer:

Some JavaScript implementations allow direct access to the [[Prototype]] property, eg via a non-standard property named

`__proto__`

. In general, it’s only possible to set an object’s prototype during object creation: If you create a new object via new Func(), the object’s [[Prototype]] property will be set to the object referenced by Func.prototype.

The reason you can’t assign to its prototype using `.prototype`

is because the `Math`

object has already been created.

Fortunately for us, we can assign new properties to the `Math`

object by simply using:

```
Math.myFunc = function() { return true };
```

In your case, this would be:

```
Math.randomBetween = function(...) { ... };
```

```
var MyMath = Object.create(Math); // empty object with prototype Math
MyMath.randomBetween = function (a, b) {
return this.floor(this.random() * (b - a + 1) + a);
};
typeof(MyMath); // object
Object.getPrototypeOf(MyMath); // Math
MyMath.PI; // 3.14...
MyMath.randomBetween(0, 10); // exactly that
```

- the
`Math`

object is the prototype of the new`MyMath`

object `MyMath`

has access to all functionality of`Math`

- you can add your custom functionality to
`MyMath`

without manipulating`Math`

- within your custom methods, use keyword
`this`

to refer to the`Math`

functionality

There is no *Monkey Patching* with this approach. This is the best way to extend JavScript `Math`

. There is no need to repeat the explanations from the other answers.