javascript闭包:隐式参数,调用者

时间:2013-04-22 10:45:41

标签: javascript dom closures prototypal-inheritance

我需要对javascript调用的元数据进行一些澄清。下面提供的代码包含SenderAsParameterFunc和NoExplicitParametersFunc,它们是从AnotherFunction的每个循环中调用的。

var Obj = function(){

Obj.SenderAsParameterFunc = function(sender, param1, param2){
// log $(sender).id;
}

Obj.NoExplicitParametersFunc = function(){

 // EXTRACT DEFAULT SENDER/CALLEE
 // I see in console Obj.NoExplicitParametersFunc.caller.arguments >> SEE REF1
}

 Obj.NoExplicitParametersFuncWithExtraArgs = function(this, par1, par2){
 // 'this' from each loop?
}

Obj.AnotherFunc = function(){

    var X = $('myselect');

    var par1 = 1;
    var par2 = 'bla';
    $.each(X.find("option"), function () {
                Obj.SenderAsParameterFunc(this, par1, par2); 
                // 'this' here references current object from 'each' loop
            });

    $.each(X.find("option"), Obj.NoExplicitParametersFunc); 
   // must be equvalent to first var, 
   // but to extract 'inner' this we have to do more magic in NoExplicitParametersFunc...

    var par1 = 1;
    var par2 = 'bla';
    $.each(X.find("option"), Obj.NoExplicitParametersFuncWithExtraArgs);
    }

}

那么应该在NoExplicitParametersFunc中编写什么来获取对每个选项的访问,因为在SenderAsParameterFunc中使用$(this)来完成?

==========

好的,总结一下我学到的东西: 如果函数没有参数

$.each(X.find("option"), Obj.NoExplicitParametersFunc);

然后默认传递'this',并且可以在函数中访问。

如果某个函数有参数

$.each(X.find("option"), function () { Obj.SenderAsParameterFunc(this, par1, par2); });

然后'this'必须作为参数(第一个?)包含在函数中可以访问。

=============

REF1:

b.Event
altKey: undefined
attrChange: undefined
attrName: undefined
bubbles: true
cancelable: false
ctrlKey: undefined
currentTarget: input#inputId
data: undefined
delegateTarget: input#inputId
eventPhase: 2
handleObj: Object
isDefaultPrevented: function ot(){return!1}
jQuery19105656534675508738: true
metaKey: false
originalEvent: Event
relatedNode: undefined
relatedTarget: undefined
shiftKey: undefined
srcElement: input#inputId
target: input#inputId
timeStamp: 1366622725473
type: "change"
view: undefined
which: undefined
__proto__: Object,

currentTarget,delegateTarget,srcElement,target ARE相同,但应该实际使用什么,最正确的方法是什么?参考文献将不胜感激!

感谢。

2 个答案:

答案 0 :(得分:1)

$.each(X.find("option"), function () {
      Obj.SenderAsParameterFunc(this);
      // 'this' here references anonymous function, 
      // from which it was called, so 'this' is sender
});

没有。此处的任何内容都未引用匿名函数(只能在$.each中作为参数访问)。 this keyword回调中的$.each确实引用了迭代项。这也回答了你的问题:

Obj.NoExplicitParametersFunc = function(i, v){
    console.log(this, i, v);
}
  

如果一个函数有参数[并在一个匿名函数表达式中调用]那么'this'必须作为一个参数(第一个?)包含在函数中可以访问。

是的,由于this对于每个函数调用都是唯一的,您必须传递其值 - 就像您不能只访问调用函数的局部变量一样,您无法访问其this值。要使用特定的此值调用函数,您可以使用.call

$.each(X.find("option"), function(i, v) {
    Obj.SenderAsParameterFunc.call(this, i, v, par1, par2);
});

答案 1 :(得分:1)

TL; DR:在您的情况下无所谓,但如果您有疑问,请使用currentTarget


我真的不明白你的第一个问题,但关于第二个问题......

当调度事件时,通常会发生此事件,例如在此页面上:

<body>
  <div>
    <img src="foobar.png" />
  </div>
</body>

如果用户点击img内的div元素,则会以这种方式触发事件

body - capturing
div - capturing
img - at target
div - bubbling
body - bubbling

因此,您可以向body添加一个监听器,您将捕获该事件。但是为了让您知道实际点击了哪个元素(在这种情况下为img),它在Internet Explorer上提供了event.target属性(srcElement)。

delegateTarget是jQuery添加的属性,如果您使用事件委派,它会提供额外的信息。我不确切知道它是什么,但你可以看看at the documentation

最后currentTarget是您附加事件的元素,如果我们将监听器添加到body,它将是body。所以每个事件的论点都是

fire body.click with { target: img, currentTarget: body }
fire div.click  with { target: img, currentTarget: div  }
fire img.click  with { target: img, currentTarget: img  }
fire div.click  with { target: img, currentTarget: div  }
fire body.click with { target: img, currentTarget: body }

根据您的行为,您将需要一个或另一个属性。