我想知道是否尝试将数组中的所有小写项目转换为大写。
我正在评估一些变体并检查了 .call()
变体是最快的变体 ( http://jsperf.com/uppercaseperformance )
使用以下代码,该代码在 Firefox (32.0.1) 中运行良好:
console.log(String.toUpperCase.call(null,['a', 'lower', 'case', 'string', 'array']))
仅在 Firefox 中输出:
A,LOWER,CASE,STRING,ARRAY <- Thats nice ;)
相同的代码在 Chrome、Safari、node.js 等中不起作用。 Chrome/Safari 输出:
TypeError: Cannot read property 'call' of undefined
node.js 输出:
TypeError: Cannot call method 'call' of undefined
.call 是否可能在错误的上下文中使用?
MDN上的浏览器兼容性网站显示应支持 .call()
。
最佳答案
String generic methods不是 ECMAScript 标准的一部分,它们仅在 Firefox 中提供。
您可以为所有其他浏览器填充它(直接从 MDN 复制):
/*globals define*/
// Assumes all supplied String instance methods already present
// (one may use shims for these if not available)
(function () {
'use strict';
var i,
// We could also build the array of methods with the following, but the
// getOwnPropertyNames() method is non-shimable:
// Object.getOwnPropertyNames(String).filter(function (methodName)
// {return typeof String[methodName] === 'function'});
methods = [
'quote', 'substring', 'toLowerCase', 'toUpperCase', 'charAt',
'charCodeAt', 'indexOf', 'lastIndexOf', 'startsWith', 'endsWith',
'trim', 'trimLeft', 'trimRight', 'toLocaleLowerCase',
'toLocaleUpperCase', 'localeCompare', 'match', 'search',
'replace', 'split', 'substr', 'concat', 'slice'
],
methodCount = methods.length,
assignStringGeneric = function (methodName) {
var method = String.prototype[methodName];
String[methodName] = function (arg1) {
return method.apply(arg1, Array.prototype.slice.call(arguments, 1));
};
};
for (i = 0; i < methodCount; i++) {
assignStringGeneric(methods[i]);
}
}());
<小时/>
请注意,使用上面的垫片只是在此基础上添加一些抽象:
String.prototype.toUpperCase.apply(['a', 'lower', 'case', 'string', 'array']);
// "A,LOWER,CASE,STRING,ARRAY"
这里有趣的部分是数组被用作 String 方法的 this
值。
根据规范( § 15.5.4.18 -> § 15.5.4.16 步骤 2),this
绑定(bind)通过内部 ToString 强制转换为字符串。算法,对于对象(注意数组是对象)调用内部 ToPrimitive算法,该算法依次调用数组的 toString
方法,该方法又调用数组的 join
具有空参数列表的方法。
也就是说,调用 .toUpperCase()
将数组作为 this
绑定(bind)传递将首先将 this
隐式强制为字符串:
['a', 'b'].toString() === ['a', 'b'].join();
['a', 'b'].join() === 'a,b';
然后 toUpperCase
会将此字符串的字符映射为其等效的大写字符。因此:
String.prototype.toUpperCase.apply(['a', 'b']) === ['a', 'b'].join().toUpperCase();
关于javascript - 为什么 String.methods 上的 .call 除了在 Firefox 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25922918/