如何将变量绑定到函数调用

时间:2014-07-29 16:39:59

标签: javascript jquery backbone.js bind

我正在创建一个已经有两个参数的函数。我想绑定一个也会被传入的变量。

this.listenTo(this.topView,this.directionChosen.bind('top');
this.listenTo(this.leftView,this.directionChosen.bind('left');
this.listenTo(this.rightView,this.directionChosen.bind('right');
this.listenTo(this.bottomView,this.directionChosen.bind('bottom');

directionChosen:function(item,move,direction) {

}

是否可以绑定变量/属性并将其作为函数中的方向传递?

我一直在寻找这样做,但可能做得不对。 感谢

2 个答案:

答案 0 :(得分:3)

如果查看doc for .bind(),可以看到它需要一个或多个参数。第一个参数是您要为函数调用设置的this指针。您必须将其作为第一个参数传递。之后的其他参数是可选的,并且是传递给实际函数的第一个参数。

此外(我无法在你的问题中说出你想要的内容),你必须传递你想传递的实际参数,而不是变量名。

所以,你这样做的方式是行不通的。您必须将所需的this值作为第一个参数传递,并且您传递的任何其他参数将首先发送到函数,而不是最后一个。


您可以使用闭包来解决您的问题,这与.bind()完全相同,但在您自己的自定义闭包中,您可以使用函数参数执行任何操作。

// method to call
directionChosen: function(item,move,direction) {

}

// code to call our method with custom arguments
var self = this;
this.listenTo(this.mainView, function(item, move) {
    self.directionChosen(item, move, 'top');
});

或者,如果top实际上是一个变量名,并且您希望将该变量的值作为参数传递(从您的问题中不清楚),它将如下所示:

// code to call our method with custom arguments
var self = this;
this.listenTo(this.mainView, function(item, move) {
    self.directionChosen(item, move, top);
});

如果你想大量使用这种post-pend参数行为,你可以创建自己的.bind()自定义版本来为你做这件事。

Function.prototype.bindAfter = function(thisPtr /* one or more args */) {
    var args = Array.prototype.slice.call(arguments);
    var self = this;
    args.shift();
    return function() {
        var newArgs = Array.prototype.slice.call(arguments).concat(args);
        return self.apply(thisPtr, newArgs);
    }
};

然后您可以像这样使用.bindAfter()

this.listenTo(this.topView,this.directionChosen.bindAfter(this, 'top'));
this.listenTo(this.leftView,this.directionChosen.bindAfter(this, 'left'));
this.listenTo(this.rightView,this.directionChosen.bindAfter(this, 'right'));
this.listenTo(this.bottomView,this.directionChosen.bindAfter(this, 'bottom'));

仅供参考,解决这个问题的蛮力方式如下:

var self = this;
this.listenTo(this.topView, function(item, move) {
    return self.directionChosen(item, move, 'top');
});
this.listenTo(this.leftView, function(item, move) {
    return self.directionChosen(item, move, 'left');
});
this.listenTo(this.rightView, function(item, move) {
    return self.directionChosen(item, move, 'right');
});
this.listenTo(this.bottomView, function(item, move) {
    return self.directionChosen(item, move, 'bottom');
});

实际创建.bindAfter()的新代码行实际上更少。


您还可以创建一个辅助函数,该函数仅针对这一个问题:

function callWithDirection(thisPtr, direction) {
    return function(item, move) {
        return thisPtr.directionChosen(item, move, direction)
    }
}

然后,您可以像这样使用它:

this.listenTo(this.topView, callWithDirection(this, 'top'));
this.listenTo(this.leftView, callWithDirection(this, 'left'));
this.listenTo(this.rightView, callWithDirection(this, 'right'));
this.listenTo(this.bottomView, callWithDirection(this, 'bottom'));

答案 1 :(得分:0)

您最近的修改会让您更清楚地了解您所寻找的内容。

这样的事情应该做。

directionChosen:function(item,move,direction) {

}

var directChosen = this.directionChosen;
function bindDirection(direction) {
    return function boundDirection(item, move){
        directionChosen.call(this, item, move, 'top');
    }
}

this.listenTo(this.mainView,bindDirection('top'));
this.listenTo(this.leftView,bindDirection('left'));
this.listenTo(this.rightView,bindDirection('right'));
this.listenTo(this.bottomView,bindDirection('bottom'));

ORIGINAL:

我注意到最近对Function.prototype.bind的痴迷。我发现它有点不必要了。通过定义新函数,您可以轻松实现更易读,几乎相同的结果。

directChosen.bind(this, 'a', 'b');

几乎与:

相同
var context = this;
function(direction){
    directChosen.call(context, 'a', 'b', direction);
}

当您阅读代码时,这种方式至少会为您提供有意义的功能声明。


编辑:

如果您仅查找direction的值'top',请执行以下操作:

function(item, move){
    directChosen.call(this, item, move, 'top');
}

如果您想要bindDirection功能,只需执行以下操作:

function bindDirection(direction) {
    return function boundDirection(item, move){
        directChosen.call(this, item, move, 'top');
    }
}