如果我想获得一个转换为小写的字符串数组,这似乎是正常的事情:
lodash = require('lodash')
lodash.map(['A', 'B'], String.prototype.toLowerCase.call)
TypeError: object is not a function
at Function.map (/Users/alejandro.carrasco/repos/cap-proxy/node_modules/lodash/dist/lodash.js:3508:27)
at repl:1:9
at REPLServer.self.eval (repl.js:110:21)
at Interface.<anonymous> (repl.js:239:12)
at Interface.EventEmitter.emit (events.js:95:17)
at Interface._onLine (readline.js:202:10)
at Interface._line (readline.js:531:8)
at Interface._ttyWrite (readline.js:760:14)
at ReadStream.onkeypress (readline.js:99:10)
at ReadStream.EventEmitter.emit (events.js:98:17)
我在代码中挖了一点,似乎问题是由createCallback包装在map中使用的传递函数产生的:
lodash.createCallback(String.prototype.toLowerCase.call)('A')
TypeError: object is not a function
at repl:1:58
at REPLServer.self.eval (repl.js:110:21)
at Interface.<anonymous> (repl.js:239:12)
at Interface.EventEmitter.emit (events.js:95:17)
at Interface._onLine (readline.js:202:10)
at Interface._line (readline.js:531:8)
at Interface._ttyWrite (readline.js:760:14)
at ReadStream.onkeypress (readline.js:99:10)
at ReadStream.EventEmitter.emit (events.js:98:17)
at emitKey (readline.js:1095:12)
但我真的不明白那里发生了什么……
我知道如果我传递这样的回调它是有效的:
function(x) {return x.toLowerCase()}
但好奇心正在扼杀我……
解决方法:
为什么
同样的原因[‘A’,’B’].map(String.prototype.toLowerCase.call)不起作用 – 它有效地使用Function.prototype.call.call(thisArg,currentValue)作为抛出TypeError的迭代器:object不是函数,因为thisArg是全局上下文(进程)而不是String.prototype.toLowerCase.
怎么样
// You expect this to be your iterator:
String.prototype.toLowerCase.call('A');
// Instead, you got this:
String.prototype.toLowerCase.call.call(thisArg, 'A');
由于thisArg必须在您的示例中处理,因此上面的行几乎与以下内容相同:
process()与此绑定到’A’.
// The "correct" invocation "should" be:
String.prototype.toLowerCase.call.call(String.prototype.toLowerCase, 'A');
固定
您可以通过传递“正确”thisArg来修复它.以下的工作,但这样的地图看起来不像函数(x){return x.toLowerCase()}给我:
['A'].map(String.prototype.toLowerCase.call, String.prototype.toLowerCase);
['A'].map(String.prototype.toLowerCase.call.bind(String.prototype.toLowerCase));
['A'].map(Function.prototype.call, String.prototype.toLowerCase);
['A'].map(Function.prototype.call.bind(String.prototype.toLowerCase));
upd ES2015和transpilers因为它现在相当成熟,我更喜欢以下内容:
['A'].map(letter => letter.toLowerCase());