Array.from TypeError:0不是函数

时间:2016-03-14 15:36:00

标签: javascript arrays

我在尝试将Array.from传递给Array.prototype.map时收到一个奇怪的错误。

let fn = Array.from.bind(Array); // [Function: bound from]

fn('test') // [ 't', 'e', 's', 't' ]

['test'].map(s => fn(s)) // [ [ 't', 'e', 's', 't' ] ]

['test'].map(fn) // TypeError: 0 is not a function

完全错误:

TypeError: 0 is not a function
    at Function.from (native)
    at Array.map (native)
    at repl:1:10
    at REPLServer.defaultEval (repl.js:260:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:429:12)
    at emitOne (events.js:95:20)
    at REPLServer.emit (events.js:182:7)
    at REPLServer.Interface._onLine (readline.js:211:10)

发生了什么事?

2 个答案:

答案 0 :(得分:9)

map使用三个参数调用其回调:条目,索引和迭代的对象。 Array.from期望如果给出第二个参数,它就是一个映射函数,因此试图在每个&#34;元素上调用它。它正在构建阵列。第一次调用时的索引0不是函数,因此Array.from失败。

换句话说,相当于

['test'].map(fn)

不是

['test'].map(e => fn(e))

而是

['test'].map((e, i, a) => fn(e, i, a))

...其中e是条目,i是其索引,a是&#34;数组&#34;由map遍历。由于i不是函数,Array.from失败。

您可以使用其他几个数组函数获得相同的功能,例如forEachsome,...

如果你经常这么做,你可能会发现有一个函数可以用来过滤除第一个参数之外的所有函数:

function passOneArg(f) {
    return function(a) { return f.call(this, a); };
}

你可以这样使用:

['test'].map(passOneArg(fn))

甚至可能

function limitArgs(f, count) {
    return function() {
        return f.apply(this, Array.prototype.slice.call(arguments, 0, count));
    };
}

然后

['test'].map(limitArgs(fn, 1))

当然,这是地球上最糟糕的两个功能名称,但你明白了......: - )

答案 1 :(得分:0)

您可以使用lodash一元

import * as lodash from 'https://cdn.jsdelivr.net/npm/lodash-es/lodash.min.js'
['ab', 'cd'].map(lodash.unary(Array.from))