我想知道尝试将数组中的所有小写项目转换为大写。
我正在评估一些变体并检查.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吗?
<{3}}网站上的浏览器兼容性显示应支持.call()
。
答案 0 :(得分:4)
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 - &gt; § 15.5.4.16步骤2),this
绑定通过内部ToString算法强制转换为字符串,对于对象(注意数组是对象)调用内部ToPrimitive算法,该算法又调用数组的toString
方法,该方法又使用空参数列表调用数组的join
方法。
也就是说,调用.toUpperCase()
将数组作为this
绑定传递将首先隐式地将this
强制转换为字符串:
['a', 'b'].toString() === ['a', 'b'].join();
['a', 'b'].join() === 'a,b';
然后toUpperCase
会将此字符串的字符映射到等效的大写字符。因此:
String.prototype.toUpperCase.apply(['a', 'b']) === ['a', 'b'].join().toUpperCase();
答案 1 :(得分:3)
这似乎是Firefox的一个特点,更多的是一个隐藏的功能,而不是一个bug。
实际上,按照标准,{p>toUpperCase
仅作为prototype method of String
提供,因此应在有效实例上调用。你当然可以尝试:
String.prototype.toUpperCase.call(null,['a', 'lower', 'case', 'string', 'array'])
在Chrome中,显然会返回:
TypeError: String.prototype.toUpperCase called on null or undefined
在其上调用call(null, ...)
时,将使用空this
引用调用实例方法。您尝试is only implemented in Firefox的静态调用样式,而不是任何当前ECMAScript标准的一部分。
答案 2 :(得分:1)
试试这个String.prototype.toUpperCase.call(['a', 'lower', 'case', 'string', 'array'])