1

I have the following javascript method:

String.prototype.includesAny = function(search) {
  var found = false;
  search.forEach(function(str) {
    if(this.toLowerCase().includes(str.toLowerCase())) {
      found = true;
    }
  });
  return found;
};

But it throws the error:

this.toLowerCase is not a function

I am thinking this is because this is not actually an instance of String at this point? Anybody knows the right way to do what I'm doing (and still use the prototype paradigm)?

3
  • You have not bound the callback function to this. use the thisArg argument of forEach. Commented Nov 2, 2016 at 19:13
  • Basically a duplicate of How to access the correct this / context inside a callback? Commented Nov 2, 2016 at 19:23
  • Just a side note: this is not the very effective implementation. You will keep scanning an array after you have found first matching string, which is meaningless. You can just return true whenever you have found the first match. Commented Feb 2, 2019 at 10:48

3 Answers 3

1

In javascript this is function scoped, so creating a new function creates a new this.

Your forEach call has a callback, which is a function, and within that function this is no longer the string, but most likely the window

The solution is to simply store a reference to whatever this is in the outer function

String.prototype.includesAny = function(search) {
    var found = false,
        input = this;
    search.forEach(function(str) {
        if (input.toLowerCase().includes(str.toLowerCase())) {
            found = true;
        }
    });
    return found;
};

Array.forEach also has an optional thisArg that can be used

String.prototype.includesAny = function(search) {
    var found = false;

    search.forEach(function(str) {
        if (this.toLowerCase().includes(str.toLowerCase())) {
            found = true;
        }
    }, this);
    return found;
};

Or even better, use Array.some

String.prototype.includesAny = function(search) {
    return search.some(function(str) {
        return this.toLowerCase().includes(str.toLowerCase());
    }, this);
};

As a sidenote, extending native prototypes is generally a bad idea.

Sign up to request clarification or add additional context in comments.

Comments

0

You're probably correct about this not being a string because you are in the foreach. So store an instance of this in a variable before entering the foreach and use that instead.

var stringToCheck = this;
search.forEach(function...

Comments

0

You need to save your this in other variable to use it in other functions scope.

Comments

Your Answer

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.