[英]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: 例如,
this
对includes
可能是一个数字:
<< 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.indexOf
的this
也不必是一个字符串的事实:
<< 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.