我正在创建一个已经有两个参数的函数。我想绑定一个也会被传入的变量。
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) {
}
是否可以绑定变量/属性并将其作为函数中的方向传递?
我一直在寻找这样做,但可能做得不对。 感谢
答案 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');
}
}