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

Kit*_*ita 12 javascript arrays

我试图找出一个单行代码使用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')
];
Run Code Online (Sandbox Code Playgroud)

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

cats.map(function (cat) {
    cat.mew();
});
// MB mews
// 503 mews
Run Code Online (Sandbox Code Playgroud)

call() 在原型上也有效.

cats.map(function (cat) {
    Cat.prototype.mew.call(cat);
});
// MB mews
// 503 mews
Run Code Online (Sandbox Code Playgroud)

这是我的最后一行,但它发出错误,我无法理解为什么:

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

// Uncaught TypeError: undefined is not a function
// at Array.map (<anonymous>)
Run Code Online (Sandbox Code Playgroud)

检查typeof Cat.prototype.mew.call说它是一个functionmap()一个参数应该是一个函数.

任何人都可以解释为什么它不起作用?我错过了什么以及在哪里纠正?

gur*_*372 6

任何人都可以解释为什么它不起作用?我错过了什么以及在哪里纠正?

错误信息说

VM1100:15 Uncaught TypeError:undefined不是函数

这意味着它正在寻找在上下文中调用该mew方法undefined.

您需要将上下文绑定为

cats.map( Cat.prototype.mew.call.bind( new Cat().mew ) );
Run Code Online (Sandbox Code Playgroud)

演示

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 ) );
Run Code Online (Sandbox Code Playgroud)

或者正如@PatrickRoberts建议的那样,你可以使用

cats.map(Function.call.bind(Cat.prototype.mew))
Run Code Online (Sandbox Code Playgroud)

避免不必要地创建一个实例 Cat

cats.map(function (cat) { Cat.prototype.mew.call(cat); }); 表达中,为什么Cat.prototype.mew.call有正确的背景?

根据规格

如果提供了thisArg参数,则每次调用callbackfn时它都将用作此值.如果未提供,则使用undefined.

所以,除非你传递像这样的上下文

cats.map( Cat.prototype.mew.call,  new Cat().mew );
Run Code Online (Sandbox Code Playgroud)

它会undefined.

  • `cats.map(Function.call.bind(Cat.prototype.mew))`会避免不必要地构造`Cat`的实例 (2认同)