2014-02-07 3 views
3

JQuery итераторов функции, такие как each имеют синтаксис похож на это:JQuery итерационные функции

.each(function(index, element)) 

, которые, казалось бы, следует, что функция согласования этой декларации придется принять 2 параметра. Что-то вроде:

function my_func(index, element){ 
    alert(index+":"+element); 
} 

Для меня это дает 2 возможные заявления:

$("li").each(my_func); 

или

$("li").each(function(index, element) {alert(index+":"+element);}); 

Первый меня смущает, потому что я не вижу index или element передается my_func , Есть ли какая-то магия в jQuery, которая знает, что my_func принимает 2 параметра, которые предоставляет each?

Во-вторых, если бы я заявил

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(), потому что тогда мне не нужно беспокоиться о том, вызывается ли функция перед ее объявлением - но это действительно предпочтение личного стиля.


Есть ли у вас объявить Callback аргументы

Для вашего последнего вопроса, вам нужно всего лишь объявить аргументы обратного вызова, если вы хотите использовать их. В 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, вы можете также рассмотреть, какой тип аргументов были переданы функции и адаптировать свое поведение соответствующим образом. Например, предположим, что вы имели простую функцию, которая HIDS элемент DOM:

function hide(elem) { 
    elem.style.display = "none"; 
} 

// usage 
var obj = document.getElementById("test"); 
hide(obj); 

Эта функция предполагает, что элем является 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"); 
+0

Я предполагаю, что когда вы объявляете переменную «my_func», она также имеет область действия, а не глобальную по своей природе. Верный? –

+0

@drew_w - yes, 'var my_func = function() {}' существует только в области, в которой он объявлен, но то же самое верно для другого способа определения функции. Функции могут быть определены в рамках других функций, и затем они ограничены только внутри этой функции. Никакой реальной разницы между двумя методами охвата. – jfriend00

+0

@ jfriend00 Спасибо за замечательный ответ. Не могли бы вы уточнить, что «функция - это то же самое, независимо от того, объявляете ли вы ее с аргументами или нет? Мой разум больше похож на мир Java/C, и я не могу понять, что это значит. –

Смежные вопросы