I want to make a JS prototype function that mimics the Python syntax of 'a' in 'abc'.
It works as expected in the first example but not in the second. What am I doing wrong?
String.prototype.in = function(input) {
return input.indexOf(this) > -1
}
console.log('a'.in('abc'))
// equivalent of 'abc'.indexOf('a') > -1
// true
console.log('a'.in(['a']))
// equivalent of ['a'].indexOf('a') > -1
// false
-
well if you want to pass in array, than one must code to handle that....epascarello– epascarello2019年07月26日 21:52:24 +00:00Commented Jul 26, 2019 at 21:52
-
2@epascarello You have it the wrong way round. The array is being passed into.Rob Kwasowski– Rob Kwasowski2019年07月26日 22:26:25 +00:00Commented Jul 26, 2019 at 22:26
1 Answer 1
Primitive values such as numbers, strings, etc.. can't have methods in javascript.
So whenever you call a method on a primitive, it will be coerced into its object form.
(Similar to "boxing" in languages like java or c#)
Small example to illustrate the difference:
// number primitive
let primitive = 12;
console.log(primitive);
// number object
let object = new Number(12);
console.log(object);
The object forms of primitives mostly behave in the same way as their primitive counter-parts, however there are a few differences, for example equality:
console.log(12 == 12); // true
console.log(new Number(12) == new Number(12)); // false
// mixed comparisons
console.log(new Number(12) == 12); // true (boxed value will be unboxed)
console.log(new Number(12) === 12); // false (strict equality)
The reason why your second example 'a'.in(['a']) is not working, is because Array.prototype.indexOf will check each element for strict equality (===).
The this string is currently in its object form, but the 'a' in the array in its primitive form - so they are not equal.
In order to get the in() function working, you need to "unbox" the string value.
You can do so by using the Object.prototype.valueOf() method, which will return the primitive value:
String.prototype.in = function(input) {
return input.indexOf(this.valueOf()) > -1
}
console.log('a'.in('abc')); // true
console.log('a'.in(['a'])); // true