将函数作为回调传递的方法
在这个:
$("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 不是一个函数,直到该行 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");