4

我发现不使用匿名函数通过将代码扁平化为更易于理解的独立函数,使我的代码更具可读性和自我记录性。所以我想打破以下结构:

function Save() {
   myVal = 3.14 // some arbitrary value
   $('#myID').each(function(index,element) {
      if ($(this).val() === myVal) {}
   });
}

进入:

function Save() {
   myVal = 3.14 // some arbitrary value
   $('#myID').each(myFunction);
}

function myFunction(index,element) {
   if ($(this).val() === myVal) {}
}

在这里使用 .bind 的问题在于,您在每个方法中丢失了 $(this) 的值,所以(我不认为)我可以将 myVal 绑定到 myFunction。

也许我可以使用element而不是this

编辑 1:我应该使用 .myClass 而不是 #myID 作为示例选择器。

编辑2:我没有在建议的解决方案中使用绑定,因为我认为绑定不起作用。

编辑 3:我感谢大家说第一个示例更具可读性。我只是在探索语言并尝试不同的想法。

4

3 回答 3

4

那么:

function Save() {
    myVal = 3.14 // some arbitrary value
    $('#myID').each(myFunction(myVal));
}

function myFunction(myVal) {
    return function(index, element) {
        if ($(this).val() === myVal) {}
    }
}
于 2013-04-09T15:29:10.490 回答
2

您不会失去对this; 您将无法访问,myVal因为myVal在内部不知道myFunction,主要是因为该函数被定义在没有定义的范围内myVal

你可以做的是这样的:

function myFunction(index, element, myVal) {
   if ($(this).val() === myVal) {}
}

进而:

function Save() {
   myVal = 3.14 // some arbitrary value
   $('#myID').each(function(index, element) {
       myFunction.call(this, index, element, myVal);
   });
}

这样,如果你里面有很多逻辑myFunction,你仍然可以把它分开,然后myFunction.each)的回调中调用。不是那个myFunction被调用,.call因为这样你可以为this(第一个参数)传递一个显式值。因此与回调内部的this相同。this.each

不过老实说,第一个选项更具可读性,并且通过像这样拆分代码,您实际上并没有获得太多收益。

于 2013-04-09T15:28:42.240 回答
2

this在这种情况下将是相同的。您无法访问的一件事是myVal. 你是对的,你不能使用Function.bind,因为那不允许你指定保留原件(通话时间)this

以下是您可以使用修改后的版本来传递myVal和保持不变的方法,我们称之为thisFunction.bindmyBind

/**
 * Binds the given function to the given context and arguments. 
 *
 * @param {function} fun The function to be bound
 * @param {object} context What to use as `this`, defaults 
 *        to the call time `this`
 * @param {object[]} customArgs Custom args to be inserted into the call
 * @param {number} index Where to insert the arguments in relationship
 *        to the call time arguments, negative numbers count from the end.
          That is, -1 to insert at the end. Defaults to a 0 (beginning of list).
 *        
 */
function myBind(fun, context, customArgs, index) {
      return function() {
          // Default the index
          index = index || 0;
          // Create the arguments to be passed, using an old trick
          // to make arguments be a real array
          var newArgs = Array.prototype.slice.call(arguments, 0);
          // Tack the customArgs to the call time args where the user requested
          var spliceArgs = [index, 0].concat(customArgs); 
          newArgs.splice.apply(newArgs, spliceArgs);
          // Finally, make that call
          return fun.apply(context || this, newArgs);  
      }
}


function Save() {
   myVal = 3.14 // some arbitrary value
   $('#myID').each(
      // myFunction wil be called with myVal as its last parameter
      myBind(myFunction, null, [myVal], -1)
   );
}

function myFunction(index, element, myVal) {
   if ($(this).val() === myVal) {
       // do it here
   }
}

为了演示这个函数的灵活性,让我们绑定多个参数,它应该插入到调用时参数的开头

function Save() {
   var myVal = 3.14, val2 = 6.28; // some arbitrary values
   $('#myID').each(
      // myFunction wil be called with myVal and val2 as its first parameter
      myBind(myFunction, null, [myVal, val2], 0);
   );
}

// Since I don't need element, it's already available as this, we don't 
// declare the element parameter here
function myFunction(myVal, val2, index) {
   if ($(this).val() === myVal || $(this.val() === val2)) {
       // do it here
   }
}

这与 Samuel Caillerie 的答案几乎相同。唯一的区别是我们创建了一个不同的版本,Function.bind它不绑定this,只是参数。此版本的另一个好处是您可以选择插入绑定参数的位置;

于 2013-04-09T15:32:10.490 回答