Как записать функцию JS, которая принимает и “вперед” переменное количество параметров?

Не знаете, в чем проблема, кажется, это работает нормально?

DECLARE @StartDate AS DATETIME
DECLARE @EndDate AS DATETIME

SET @StartDate = NULL
SET @EndDate = NULL

IF (@StartDate IS NOT NULL AND @EndDate IS NOT NULL) 
    BEGIN
        Select 'This works just fine' as Msg
    END
Else
    BEGIN
    Select 'No Lol' as Msg
    END
6
задан bcat 25 October 2009 в 03:20
поделиться

2 ответа

Решение этой проблемы требует знания двух концепций JavaScript.

Первая - это специальная локальная переменная arguments , которая может использоваться для доступа к аргументам функции, не зная их имени и он работает как массив. Однако arguments - это не массив , а «подобный массиву» - имеющий свойства с именем 0..n-1 , где n - количество аргументов функции, а свойство - объект length . Простое демонстрационное использование может быть таким:

function f (a) { // can include names still, if desired
    // arguments instanceof Array -> false (exceptions to this?)
    var firstArg = arguments[0]
    // a === firstArg -> always true
    // iterate all arguments, just as if it were an Array:
    for (var i = 0; i < arguments.length; i++) {
        alert(i + " : " + arguments[i])
    }
}
f("a","b","c")

Вторая функция - Function.apply , которая будет вызывать функцию с определенным контекстом ( this при ее вызове) с аргументами, которые являются результатом раскрытие объекта, подобного массиву. Но см. 1 .

Таким образом, сложив все вместе:

function fireStartedEvent() {
    for(var i = 0; i < startedListeners.length; i++) {
        // jQuery will often pass in "cute" things, such as a element clicked
        // as the context. here we just pass through the current context, `this`,
        // as well as the arguments we received.
        var arg = Array.prototype.slice.call(arguments)
        startedListeners[i].apply(this, args)
    }
}

1 В то время как спецификация ECMAScript вызывает только объект, подобный массиву, Function.apply не универсально работает с объектом, подобным «массиву», и ряд общих реализаций требует правильного объекта Array . Предупреждение из ссылки Function.apply :

Примечание. Большинство браузеров, включая Chrome 14 и Internet Explorer 9 , по-прежнему не принимают массив, как объекты, и вызовет исключение [если передан объект, не являющийся массивом]. [FireFox был исправлен в версии 4.]

К счастью, существует относительно простая идиома для преобразования «вроде массива»

8
ответ дан 8 December 2019 в 18:38
поделиться

Я думаю, что «применить» и «аргументы» - это две концепции JavaScript, которые вы можете использовать здесь:

function fireStartedEvent() {
  for (var i = 0; i < startedListeners.length; i++) {
    startedListeners[i].apply(startedListeners[i], arguments);
  }
}

Вот код из моей консоли Firebug, с которой я пробовал это:

a = function(foo) { alert('a: ' + foo); };
b = function(foo, bar) { alert('b: ' + foo + ', ' + bar); };

startedListeners = [a, b];

function fireStartedEvent() {
  for (var i = 0; i < startedListeners.length; i++) {
    startedListeners[i].apply(startedListeners[i], arguments);
  }
}


fireStartedEvent('one', 'two');
5
ответ дан 8 December 2019 в 18:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: