在MDN String页面上,他们有一个例子来填充String.includes。
String.prototype.includes = function() {'use strict';
return String.prototype.indexOf.apply(this, arguments) !== -1;
};
他们是否有理由直接在String.prototype.indexOf.apply
使用indexOf
与来电this
?
String.prototype.includes = function(searchString, position) {'use strict';
return this.indexOf(searchString, position) !== -1;
};
答案 0 :(得分:7)
答案是使用this.indexOf
的polyfill版本不符合spec for String.prototype.includes
,这允许this
成为可转换为字符串的任何内容:
如果 searchString 显示为的子字符串,则将此对象转换为字符串 ...
例如,this
到includes
可以是一个数字:
<< String.prototype.includes.call(1, '1')
>> true
这类似于String.prototype.indexOf
,根据spec,this
也不要求<< String.prototype.indexOf.call(1, '1')
>> 0
为字符串。
includes
如果this.indexOf
已实施,则OP建议使用String.prototype.includes = function(searchString, position) {'use strict';
return this.indexOf(searchString, position) !== -1;
};
:
includes
然后,如规范所允许,使用非字符串this
调用<< String.prototype.includes.call(1, '1')
>> TypeError: undefined is not a function
会产生运行时错误:
String.prototype.includes = function() {'use strict';
return String.prototype.indexOf.apply(this, arguments) !== -1;
};
而MDN polyfill:
this
正常运行,利用String.prototype.indexOf
<< String.prototype.includes.call(1, '1')
>> true
也不一定是字符串这一事实:
indexOf
所以我认为MDN polyfill的编写方式不是为了防止在某个特定的字符串对象上覆盖prototype.apply
方法,或者作为一种简写来避免必须列出参数,或者由于某些Crockfordian偏好对于{{1}}成语,而是为了正确实现规范。
答案 1 :(得分:3)
是的,有理由这样做。它确保即使字符串的indexOf
属性被覆盖,仍将使用原始indexOf
属性。
如果我们使用new String
构造函数,那么这样的事情是可能的。
var s = new String('test');
s.indexOf = function() {
throw new Error('this is bad');
};
s.indexOf('test');//Throws error.
答案 2 :(得分:0)
String.prototype.indexOf
可以使用一个或两个参数,并且使用apply可以让您简单地传递进来的内容,而不必担心类型或状态检查。