0

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

asked Jul 26, 2019 at 21:49
2
  • well if you want to pass in array, than one must code to handle that.... Commented Jul 26, 2019 at 21:52
  • 2
    @epascarello You have it the wrong way round. The array is being passed into. Commented Jul 26, 2019 at 22:26

1 Answer 1

4

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

answered Jul 26, 2019 at 22:09
Sign up to request clarification or add additional context in comments.

1 Comment

This is correct, I've forgotten that 'this' is passed an object. valueOf or '"' + this "'" will do the trick.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.