如果我想将一个字符串数组转换为小写,这似乎是正常的事情:

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 is not a function 因为你的 thisArg 是全局上下文( process )而不是 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 在您的示例中绑定(bind)到 process,因此上面的行与以下内容几乎相同:process()this 绑定(bind)到 'A'

// The "correct" invocation "should" be:
String.prototype.toLowerCase.call.call(String.prototype.toLowerCase, 'A');

使固定

您可以通过传递“正确” thisArg 来修复它。以下的工作,但这样的 map s 看起来并不比 function(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());

关于javascript - 为什么 `lodash.map([' A'], String.prototype.toLowerCase.call)` 不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25318727/

10-13 08:39