2016-08-15 8 views
2

Я учусь пост для решения в дребезга:При каких обстоятельствах контекст используется?

Can someone explain the "debounce" function in Javascript

Я изо всех сил думать о ситуации, когда

func.apply(context, arguments); 

необходимо, вместо того, чтобы просто с использованием

func(); 

Я думаю, что 99% шансов, что он будет использоваться только как функция. При каких обстоятельствах это будет привязано к объекту? Может ли кто-нибудь показать здесь пример? Благодарю.

+0

'function() {console.log (" hello "+ this.name); } 'это функция, которая использует контекст' function.call ({name: "bob"}) ', это заставит его изменить свой вывод. Нетривиальный пример 'Array.prototype.slice.call (arguments)' - очень распространенный шаблон, который вызывает 'slice' с контекстом объекта' arguments' для создания массива. Проще говоря, некоторые функции используют контекст, и в этом случае 'call' /' apply' вполне может его предоставить, другие функции не выполняются, и в этом случае настройка контекста не имеет значения.Таким образом, не устанавливая контекст, некоторые вызовы не сработают. Добавление его более общее. – vlaz

+0

@Vid Я ценю быстрый комментарий, но я действительно не спрашиваю о том, как работает контекст. Мне интересен пример, когда эта функция debouncing используется как метод, а не простая функция. Я просто не вижу смысла использовать «apply» здесь. Спасибо за ваш комментарий. –

+0

Ну, вы не ЗНАЕТ, какая функция будет отклонена. Это может быть один с контекстом или без него, поэтому добавление контекста полезно. Вы не можете гарантировать, что функция будет или не будет использовать контекст при дебюте. – vlaz

ответ

1

Есть две вещи, здесь происходит относительно использования apply:

function debounce(func, wait, immediate) { 
    var timeout; 
    return function() { 
     var context = this, 
     args = arguments; 
     clearTimeout(timeout); 
     timeout = setTimeout(function() { 
      timeout = null; 
      if (!immediate) func.apply(context, args); 
     }, wait); 
     if (immediate && !timeout) func.apply(context, args); 
    }; 
}; 

Во-первых, context настоящее время захвачены за пределами setTimeout обратного вызова. Так что любое правило привязки используется для определения начального контекста (который зависит от того, как вызываемая функция вызывается позже), она передается функции обратного вызова.

В качестве альтернативы, вы можете сделать что-то вроде:

setTimeout(function() { 
    ... 
    func.apply(this, args); 
}.bind(this), wait); 

Второе, что происходит, является сохранение аргументов. apply здесь используется как способ передачи аргументов (опять же, что важно зафиксировано вне обратного вызова setTimeout), который вы передадите исходной функции. Потому что он принимает array (в отличие от call), он обеспечивает легкую передачу.

Так что, если вы что-то вроде как:

debouncedFunction(a, b) 

Внутренний func называется соответственно, как func(a, b).

+0

Большое спасибо за подробное объяснение. Теперь я могу понять контекстную часть. Но с частью аргументов, это не просто вызов функции, как лучший способ: func (args)? Зачем беспокоиться о применении только аргументов? –

+1

Таким образом, ключ применяется, чтобы вы могли передавать все возрасты в виде массива. Как вы это делаете, представьте себе функцию, которая принимает два или три аргумента. Первый будет массивом аргументов, а остальные будут неопределенными ... что явно не то, что вы хотите. Имеет ли это смысл? – aw04

+0

Да, теперь это совершенно ясно. Благодарю. –

1

debounce предназначен для работы с функциями, вызываемыми любым способом. Если вызывающая функция вызывается с контекстом или с аргументами, они должны быть переданы при вызове с debounce.

Так что, если вы, как правило, сделать вызов, как:

foo.method(arg1, arg2); 

, то вы также должны быть в состоянии написать:

debounced_method = debounce(foo.method); 
foo.debounced_method(arg1, arg2); 

Тогда при вызове метода, он получает this = foo и arguments = arg1, arg2.