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

时间:2015-02-21 06:04:31

标签: javascript prototype this

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;
};

3 个答案:

答案 0 :(得分:7)

答案是使用this.indexOf的polyfill版本不符合spec for String.prototype.includes,这允许this成为可转换为字符串的任何内容:

  

如果 searchString 显示为的子字符串,则将此对象转换为字符串 ...

例如,thisincludes可以是一个数字:

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

这类似于String.prototype.indexOf,根据specthis也不要求<< 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可以让您简单地传递进来的内容,而不必担心类型或状态检查。