.each(function(index, element))
这似乎意味着匹配此声明的函数必须采用2个参数。类似的东西:
function my_func(index, element){
alert(index+":"+element);
}
对我来说,这给出了两个可能的声明:
$("li").each(my_func);
或
$("li").each(function(index, element) {alert(index+":"+element);});
第一个让我感到困惑,因为我没有看到index
或element
传递给my_func
。 jQuery中是否有一些魔术知道my_func
需要each
提供的2个参数?
其次,如果我宣布了
var my_func= function(index, element){
alert(index+":"+element);
}
这会改变什么。我的理解是,第一个是声明,第二个是表达,但是,在这种情况下,它们的行为应该相同吗?
最后,我看到的大多数each
实现都是这样的:
$("li").each(function(){alert(this)});
each
回调的所有参数都是可选的吗?
答案 0 :(得分:5)
将函数作为回调传递的方法
在此:
$("li").each(my_func);
您只是将对my_func
的引用传递给.each()
方法。每个方法本身都会在调用它时将两个参数传递给该函数。如果你想访问这两个参数,那么你可以在你自己的my_func
定义中将它们声明为参数,但你不必这样做。无论你是否声明它们,参数都会存在。
您可以通过多种不同的方式声明my_func:
// somewhat normal way and you can easily access the index and element arguments
function my_func(index, element) {
// code here
}
// if you don't need index and element, you don't need to declare them
// but they are still actually there and can be reached via the arguments object
function my_func() {
// code here
console.log(arguments[0]); // index
}
使用var
之间的区别:
var my_func= function(index, element){
alert(index+":"+element);
}
和
function my_func(index, element){
alert(index+":"+element);
}
主要是计时之一。在第二个中,my_func
被定义为函数,只要它所在的javascript文件被定位和解析,并且它定义的范围变为实时并且可用"就像"它被声明在定义范围的最顶端。这通常被称为"吊装"将定义提升到定义范围的顶部。
在第一个中,my_func
不是函数UNTIL,JS行在该javascript文件的正常执行流程中执行。
除了时间,你可以互换地使用这两者。如果个人更喜欢function xxx()
表格,因为我不必担心该功能是否在其声明运行之前被调用 - 但这实际上是个人风格偏好。
您是否必须声明回调参数
对于上一个问题,如果要使用它们,只需要声明回调的参数。在javascript中,函数是完全相同的函数,无论您是否使用参数声明它(在C ++等语言中都不是这样),因此如果您想通过名称访问它们,则只需要声明它们。
javascript中的函数参数声明是可选的。您可以声明多于传递给函数的函数,并且可以声明少于传递给函数的函数。在javascript中都不会导致任何类型的错误。
我们假设你有这段代码:
function callWithDelay(t, fn, arg1, arg2) {
setTimeout(function() {
fn(arg1, arg2);
}, t);
}
使用它的预期方法是定义一个带有两个参数的函数,并将其作为fn
参数传递。
function myFunc(msg, color) {
var obj = document.getElementById("error")
obj.innerHTML = msg;
obj.style.color = color;
}
callWithDelay(2000, myFunc, "Both first and last name are required", "red");
但是,您不必传递具有这些参数的函数。您可以这样做(通过arguments
对象而不是名称访问参数):
function myFunc() {
var obj = document.getElementById("error")
obj.innerHTML = arguments[0];
obj.style.color = arguments[1];
}
callWithDelay(2000, myFunc, "Both first and last name are required", "red");
或者,您可以传递一个甚至不需要这些参数的函数:
function myFunc() {
document.getElementById("error").style.display = "none";
}
callWithDelay(2000, myFunc);
callWithDelay
函数并不关心您传递的函数引用类型。它几乎可以是任何功能。 callWithDelay
函数会将两个参数传递给它在调用时传递给它的回调,但它是否完全取决于接收函数是否使用这些参数。在最后一个例子中,我在调用时忽略了callWithDelay
的最后两个参数。当你离开一个参数时(在调用列表的末尾),该参数只是undefined
。在javascript undefined
中是合法的值。因此,当我将它们从callWithDelay(2000, myFunc)
调用时,它们是undefined
,因此undefined
是作为其两个参数传递给myFunc
回调的内容。在这种情况下,由于没有使用这些论点,没有人关心它们是undefined
。
功能重载 - 检查传递的参数类型
在javascript中,您还可以检查传递给函数的参数类型,并相应地调整您的行为。例如,假设您有一个隐藏DOM元素的简单函数:
function hide(elem) {
elem.style.display = "none";
}
// usage
var obj = document.getElementById("test");
hide(obj);
此函数假定elem是一个DOM元素,只有在传递的内容时才会起作用。但是,如果我们还想允许某人传递id
元素,该怎么办?我们可以检查传递给hide
的参数,看看它是否是一个字符串,如果是,我们可以将其视为一个id值。
function hide(elem) {
// if a string was passed, find the DOM object using that string as an id
if (typeof elem === "string") {
elem = document.getElementById(elem);
}
elem.style.display = "none";
}
// first usage
var obj = document.getElementById("test1");
hide(obj);
// second uage
hide("test2");
现在,假设我们不仅要允许传递单个DOM元素,还要允许DOM元素数组,以便该函数可以对数组中的每个DOM元素进行操作。
function hide(elem) {
// if a string was passed, find the DOM object using that string as an id
if (typeof elem === "string") {
document.getElementById(elem).style.display = "none";
} else if (typeof elem === "object" && Object.prototype.toString.call(elem) === "[object Array]") {
// an array was passed
for (var i = 0; i < elem.length; i++) {
elem[i].style.display = "none";
}
} else {
// only a single DOM element was passed
elem.style.display = "none";
}
}
// usages
hide(obj);
hide([obj1, obj2, obj3]);
hide("test");