使用map()调用数组中对象的方法

12

我正在尝试使用map编写一行代码。

这是一个简单的设置。

function Cat(name) {
    this.name = name;
    // FYI: using __proto__ is discouraged. thanks @KarelG
    this.__proto__.mew = function () {
        console.log(this.name + " mews");
    };
}

var cats = [
    new Cat('MB'),
    new Cat('503')
];

然后,我可以使用map()来调用猫中的mew方法。

cats.map(function (cat) {
    cat.mew();
});
// MB mews
// 503 mews

call() 在原型上同样有效。

cats.map(function (cat) {
    Cat.prototype.mew.call(cat);
});
// MB mews
// 503 mews

这是我的最终一行代码,但是它会产生错误,我不明白为什么:

cats.map(Cat.prototype.mew.call);

// Uncaught TypeError: undefined is not a function
// at Array.map (<anonymous>)

检查 typeof Cat.prototype.mew.call,它应该是一个function,而且map()的参数应该是一个函数。

有人能解释为什么它不起作用吗? 我错过了什么,需要在哪里进行更正?


1
是的,它应该像这样:cats.map((Cat) => Cat.mew.call()); 或者像这样:cats.map(function(Cat) { Cat.mew.call()}); - Aswin Ramesh
2
只是提供信息,使用__proto__将函数添加到内部[[Prototype]]是不鼓励的(主要是由于原型的性质可能会影响性能)。即使有一个支持__proto__的函数(该函数是Object.setPrototypeOf()),我也不应该使用它。 - KarelG
1个回答

6

请问有人能解释一下为什么它不起作用吗?我错过了什么,需要在哪里进行更正?

错误信息显示:

VM1100:15 抛出 TypeError: undefined is not a function

这意味着它要在一个未定义的上下文中调用 mew 方法。

您需要绑定上下文,如下:

cats.map( Cat.prototype.mew.call.bind( new Cat().mew ) );

演示

function Cat(name) {
    this.name = name;
    this.__proto__.mew = function () {
        console.log(this.name + " mews");
    };
}

var cats = [
    new Cat('MB'),
    new Cat('503')
];
cats.map( Cat.prototype.mew.call.bind( new Cat().mew ) );

或者如@PatrickRoberts建议的那样,您可以使用。
cats.map(Function.call.bind(Cat.prototype.mew))

为了避免不必要地创建一个 Cat 实例,
在表达式 cats.map(function (cat) { Cat.prototype.mew.call(cat); }); 中,为什么 Cat.prototype.mew.call 有正确的上下文? 根据规范
如果提供了 thisArg 参数,它将被用作每次调用 callbackfn 时的 this 值。 如果未提供,则使用 undefined。
因此,除非您像这样传递上下文:
cats.map( Cat.prototype.mew.call,  new Cat().mew );

这将会是未定义的


1
谢谢,你的代码有效。在 cats.map(function (cat) { Cat.prototype.mew.call(cat); }); 表达式中,为什么 Cat.prototype.mew.call 有正确的上下文? - Kita
2
cats.map(Function.call.bind(Cat.prototype.mew)) would avoid needlessly constructing an instance of Cat - Patrick Roberts
1
@Kita在map中(根据规范),除非显式传递上下文,否则它将被视为未定义。 - gurvinder372

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接