В этом руководстве вы узнаете о методе JavaScript bind()
и узнаете, как его эффективно применять.
Метод bind()
возвращает новую функцию, при вызове которой this
устанавливает определенное значение.
Ниже показан синтаксис:
fn.bind(thisArg[, arg1[, arg2[, ...]]])
В этом синтаксисе метод bind()
возвращает копию функции fn
с конкретным значением this
( thisArg
) и аргументами( arg1
, arg2
, …).
В отличие от методов call()
и apply()
, метод bind()
не выполняет функцию немедленно. Он просто возвращает новую версию функции, для которой this
задан аргумент thisArg
.
Использование JavaScript bind()
для привязки функций
Когда вы передаете метод объект другой функции в качестве обратного вызова, this
теряется. Например:
let person = { name: 'John Doe', getName: function() { console.log(this.name); } }; setTimeout(person.getName, 1000);
Выход:
undefined
Как видно из вывода, person.getName()
возвращает undefined
вместо 'John Doe'
.
Это связано с тем, что setTimeout()
получает функцию person.getName
отдельно от объекта person
.
Заявление:
setTimeout(person.getName, 1000);
можно переписать как:
let f = person.getName; setTimeout(f, 1000); // lost person context
Значение this
внутри функции setTimeout()
устанавливается на глобальный объект в нестрогом режиме и undefined
в строгом режиме.
Поэтому, когда вызывается callback person.getName
, name
не существует в глобальном объекте, оно установлено в undefined
.
Чтобы решить эту проблему, вы можете обернуть вызов метода person.getName
в анонимную функцию, например:
setTimeout(function() { person.getName(); }, 1000);
Это работает, потому что он получает person
из внешней области видимости, а затем вызывает метод getName()
.
Или вы можете использовать метод bind()
:
let f = person.getName.bind(person); setTimeout(f, 1000);
В этом коде:
- Сначала привяжите метод
person.getName
к объектуperson
. - Во-вторых, передайте связанную функцию
f
сthis
значением, установленным для объектаperson
, в функциюsetTimeout()
.
bind()
для заимствования методов из другого объекта
Предположим, у вас есть объект runner
, который имеет метод run
():
let runner = { name: 'Runner', run: function(speed) { console.log(this.name + ' runs at ' + speed + ' mph.'); } };
И объект flyer
с методом fly()
:
let flyer = { name: 'Flyer', fly: function(speed) { console.log(this.name + ' flies at ' + speed + ' mph.'); } };
Если вы хотите, чтобы объект flyer
мог запускаться, вы можете использовать метод bind()
для создания функции run()
с атрибутом this
для объекта flyer
:
let run = runner.run.bind(flyer, 20); run();
В этом заявлении:
- Вызовите метод
bind()
методаrunner.run()
и передайте объект flyer в качестве первого аргумента и 20 в качестве второго аргумента. - Вызовите функцию
run()
.
Выход:
Flyer runs at 20 mph.
Возможность заимствовать метод объекта без создания копии этого метода и поддерживать его в двух разных местах очень эффективна в JavaScript.
Заключение
- Метод
bind()
создает новую функцию, при вызове которойthis
устанавливает заданное значение. - Метод
bind()
позволяет объекту заимствовать метод у другого объекта без создания копии этого метода. Это известно как заимствование функций в JavaScript.