如何将作为另一个对象的属性的函数传递给函数并在javascript中调用它?

时间:2018-07-02 02:23:48

标签: javascript function object

如果我在Javascript中有一个对象,并且它的属性之一是一个函数:

function cow() {

    this.timesMooed = 0;

    this.sayMoo = function () {
        this.timesMooed++;
        return "moo";
    };
}

说我还有另一个函数,它将某个函数作为参数,调用它并记录结果:

var actionResults = [];
function doAction(action) {
    actionResults.push(action());
}

现在让我们将其付诸实践,看看会发生什么:

var jerry = new cow();
doAction(jerry.sayMoo);
console.log(actionResults);
// Outputs ["moo"] -this is correct
console.log(jerry.timesMooed);
// Outputs 0 -uh oh

如何传递函数,以便Jerry正在运行该函数?

4 个答案:

答案 0 :(得分:3)

当您将引用传递给函数doAction并使用action()进行调用时,调用上下文将更改,这就是确定this的值的原因。您需要使用bind来将this的值锁定为jerry

function cow() {
    this.timesMooed = 0;
    this.sayMoo = function () {
        this.timesMooed++;
        return "moo";
  }
}

var actionResults = [];
function doAction(action) {
    actionResults.push(action());
}

var jerry = new cow();
// use bind, which makes a function with `this` set properly
doAction(jerry.sayMoo.bind(jerry));

console.log(actionResults);
console.log(jerry.timesMooed);

或者,您可以使用箭头功能=>来按词法绑定this

function cow() {
    this.timesMooed = 0;
    // use arrow function here instead
    this.sayMoo = () => {
        this.timesMooed++;
        return "moo";
  }
}

var actionResults = [];
function doAction(action) {
    actionResults.push(action());
}

var jerry = new cow();
// no need to bind() now
doAction(jerry.sayMoo);

console.log(actionResults);
console.log(jerry.timesMooed);

答案 1 :(得分:1)

问题是在方法中使用了this关键字,我们从接收者对象中调用了该方法,而this未绑定到我们希望它绑定到该对象的对象,即jerry情况。

请注意,当我们需要将特定对象绑定到函数的this值时,必须显式设置方法和函数中的this值。

解决方案

解决方案易于使用正确的上下文

即我们希望this引用jerry,因此在使用jerry对象的sayMoo方法调用doAction方法时,请使用绑定函数调用并将jerry作为此参数传递

doAction(jerry.sayMoo.bind(jerry));

答案 2 :(得分:1)

尝试创建构造函数

       class cow {   
            constructor(){
               this.timesMooed = '';
            }      
            sayMoo() {
               this.timesMooed+=1;
               return "moo";
            }
        }
            
            var actionResults = [];
            function doAction(action) {
            actionResults.push(action);
            }
            
            var jerry = new cow();
            doAction(jerry.sayMoo());
            console.log(actionResults);
            console.log(jerry.timesMooed);

答案 3 :(得分:0)

正如@Mark_M所说,更好的方法是使用箭头功能,但是此功能迫使您使用ES6而不是ES5,因为bound function是ES5中引入的。 另一种方法是利用可变范围的好处,例如:

        function cow() {
            this.timesMooed = 0;
            var that = this;
            this.sayMoo = function (){
                that.timesMooed++;
                return "moo";
            }
        }

        ...