javascript - Using prototype apply vs this to call function - Stack Overflow

On the MDN String page they have an example to polyfill String.includes.String.prototype.includes = fun

On the MDN String page they have an example to polyfill String.includes.

String.prototype.includes = function() {'use strict';
    return String.prototype.indexOf.apply(this, arguments) !== -1;
};

Is there a reason they used String.prototype.indexOf.apply vs calling indexOf directly on this?

String.prototype.includes = function(searchString, position) {'use strict';
    return this.indexOf(searchString, position) !== -1;
};

On the MDN String page they have an example to polyfill String.includes.

String.prototype.includes = function() {'use strict';
    return String.prototype.indexOf.apply(this, arguments) !== -1;
};

Is there a reason they used String.prototype.indexOf.apply vs calling indexOf directly on this?

String.prototype.includes = function(searchString, position) {'use strict';
    return this.indexOf(searchString, position) !== -1;
};
Share Improve this question edited Feb 21, 2015 at 6:06 JAAulde 19.6k5 gold badges56 silver badges64 bronze badges asked Feb 21, 2015 at 6:04 Eric MajerusEric Majerus 1,2383 gold badges15 silver badges23 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 7

The answer is that the version of the polyfill using this.indexOf would not conform to the spec for String.prototype.includes, which allows this to be anything convertible to a string:

If searchString appears as a substring of the result of converting this object to a String...

For instance, the this to includes could be a number:

<< String.prototype.includes.call(1, '1')
>> true

This is analogous to String.prototype.indexOf, which according to spec also does not require its this to be a string.

<< String.prototype.indexOf.call(1, '1')
>> 0

If includes is implemented as the OP suggests with this.indexOf:

String.prototype.includes = function(searchString, position) {'use strict';
    return this.indexOf(searchString, position) !== -1;
};

Then calling includes with a non-string this, as allowed by the spec, generates a run-time error:

<< String.prototype.includes.call(1, '1')
>> TypeError: undefined is not a function

Whereas the MDN polyfill:

String.prototype.includes = function() {'use strict';
    return String.prototype.indexOf.apply(this, arguments) !== -1;
};

works correctly, taking advantage of the fact that the this for String.prototype.indexOf also need not be a string:

<< String.prototype.includes.call(1, '1')
>> true

So I imagine the MDN polyfill is written that way not to protect against the indexOf method being overwritten on some particular string object, or as a shorthand to avoid having to list out parameters, or due to some Crockfordian preference for the prototype.apply idiom, but rather in order to correctly implement the spec.

Yes, there is a reason to do this. It ensures that even if the indexOf property of the string has been overwritten, the original indexOf property will still be used.

Such a thing is possible if we use the new String constructor.

var s = new String('test');
s.indexOf = function() {
    throw new Error('this is bad');
};
s.indexOf('test');//Throws error.

String.prototype.indexOfcan take one or two parameters, and using apply allows you to simply pass along what came in, as it came in, without worrying about type or presence checks.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745179199a4615340.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信