1

I try to use includes in prototype but it does not work but I do not get the expected results:

Number.prototype.inList = function (list) {
  return list.includes(this);
}

let value = 0;

let find1 = value.inList([0,1]);
let find2 = [0,1].includes(value);

console.log("find1", find1); // false
console.log("find2", find2); // true
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
A.Baudouin
  • 2,855
  • 3
  • 24
  • 28
  • I assume you understand the risks of overriding built in prototypes.? – Keith Nov 14 '21 at 10:06
  • I don't override includes, it is a new function inList. I edit my question which could be confusing... – A.Baudouin Nov 14 '21 at 10:10
  • Your overriding a built in Number. Have you ever wondered why there is no `Array.contains`?, A very popular lib called mooTools is to blame for that one, IOW: And the ES spec had to be changed and called it includes instead , all because a popular lib decided to alter Array.prototype with a function it decided to implement in its way. Not saying you don't do this, but just pointing out the risks of overriding a built-in's prototype, and is the reason most libs avoid doing it. For example underscore could have implemented it's lib via the prototype, let's say it's a good job they didn't. – Keith Nov 15 '21 at 08:56

2 Answers2

3

Using Number#valueOf:

The valueOf() method returns the wrapped primitive value of a Number object.

Number.prototype.inList = function (list) {
  return list.includes(this.valueOf());
}

let value = 0;
console.log(value.inList([0,1]));
Majed Badawi
  • 27,616
  • 4
  • 25
  • 48
3

This happens in non strict mode, where compatibility requires that this is always an object, not a primitive. So in your case this is an instance of the Number constructor, and of course that object does not occur in your list.

In strict mode your code works, as this will be the primitive value (number)

Number.prototype.inList = function (list) {
  "use strict";
  return list.includes(this);
}

let value = 0;

let find1 = value.inList([0,1]);
let find2 = [0,1].includes(value);

console.log("find1", find1); // true
console.log("find2", find2); // true

Here the strict mode is only effective on the function -- and this is enough for this issue. If your script has no "legacy dependencies", you should better set it globally.

trincot
  • 317,000
  • 35
  • 244
  • 286