简体   繁体   English

使用原型apply vs this来调用函数

[英]Using prototype apply vs this to call function

On the MDN String page they have an example to polyfill String.includes. MDN String页面上,他们有一个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.indexOf.apply VS调用indexOf直接this

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

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: 答案是使用this.indexOf版本不符合String.prototype.includes规范 ,它允许this是任何可转换为字符串的东西:

If searchString appears as a substring of the result of converting this object to a String ... 如果searchString显示为将此对象转换为String的结果的字符串 ...

For instance, the this to includes could be a number: 例如, thisincludes可能是一个数字:

<< 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 ,根据该符合规范也并不要求其this是一个字符串。

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

If includes is implemented as the OP suggests with this.indexOf : 如果includes是按照OP建议使用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: 然后主叫includes与非字符串this ,所允许的规格,产生运行时错误:

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

Whereas the MDN polyfill: 而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.indexOfthis也不必是一个字符串的事实:

<< 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. 因此,我认为MDN polyfill的编写方式不是为了防止indexOf方法被覆盖在某个特定的字符串对象上,或者作为一种速记来避免必须列出参数,或者由于某些Crockfordian对prototype.apply习惯用法的偏好,而是为了正确实施规范。

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. 它确保即使字符串的indexOf属性已被覆盖,仍将使用原始的indexOf属性。

Such a thing is possible if we use the new String constructor. 如果我们使用new String构造函数,这样的事情是可能的。

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

String.prototype.indexOf可以使用一个或两个参数,并且使用apply允许您简单地传递进来的内容,而不必担心类型或存在检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM