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

Eri*_*rus 4 javascript prototype this

MDN String页面上,他们有一个polyfill String.includes的示例.

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

是否有理由直接使用String.prototype.indexOf.applyvs indexOf直接呼叫this

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

小智 7

答案是使用的polyfill的版本this.indexOf不符合规范String.prototype.includes,允许this任何可转换为字符串的东西:

如果searchString显示为将此对象转换为String的结果的字符串 ...

例如,thisto includes可以是一个数字:

<< String.prototype.includes.call(1, '1')
>> true
Run Code Online (Sandbox Code Playgroud)

这类似于String.prototype.indexOf,根据规范也不要求它this是一个字符串.

<< String.prototype.indexOf.call(1, '1')
>> 0
Run Code Online (Sandbox Code Playgroud)

如果includes按OP建议实施this.indexOf:

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

然后,在规范允许的情况下includes使用非字符串调用会this生成运行时错误:

<< String.prototype.includes.call(1, '1')
>> TypeError: undefined is not a function
Run Code Online (Sandbox Code Playgroud)

而MDN polyfill:

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

正常工作,利用thisfor String.prototype.indexOf也不必是字符串的事实:

<< String.prototype.includes.call(1, '1')
>> true
Run Code Online (Sandbox Code Playgroud)

因此,我认为MDN polyfill的编写方式不是为了防止indexOf在某些特定的字符串对象上覆盖该方法,或者作为一种速记来避免必须列出参数,或者由于Crockfordian对该prototype.apply成语的偏好,而是为了顺序正确实施规范.