JavaScript метод bind()
Определение и применение
JavaScript метод bind() возвращает новую функцию, которая вызывается как метод объекта, устанавливая ее
контекст исполнения (this, значения контекста вызова) в указанное значение. В качестве аргументов эта
функция будет получать аргументы, переданные методу bind(), за которыми следуют аргументы, переданные уже
непосредственно новой функции.
Поддержка браузерами
Спецификация: ecma262
Поддерживается во всех основных браузерах с 2015 года.
| Возможность | Компьютеры | Мобильные | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
bind | 7 | 12 | 4 | 11.6 | 5.1 | 18 | 4 | 12 | 6 | 1.0 | 4.4 | 6 |
поддерживаетсяс ограниченияминет поддержкинет данных≤31 — не позднее версии 31
JavaScript синтаксис:
// без передачи дополнительных аргументов, которые должны быть связаны с функцией
func.bind( thisArg );
//с указанием дополнительных аргументов, которые должны быть связаны с функцией
func.bind( thisArg, arg1, ...argX );
Спецификация
ECMAScript — Function.prototype.bind().
Значения параметров
| Параметр | Описание |
|---|---|
thisArg |
Значение this (контекста вызова) внутри целевой функции. Значение игнорируется, если связанная
функция создается с помощью оператора new. Необязательный параметр. При пропуске
используется undefined.
|
args |
Ноль или более значений аргументов, которые должны быть связаны с функцией. Необязательный параметр. |
Возвращаемое значение
Новая связанная функция; исходная функция при вызове bind() не выполняется. Её name получает
префикс bound , а length уменьшается на число заранее переданных аргументов, но не ниже
нуля.
Исключения
| Тип исключения | Описание |
|---|---|
TypeError |
Возникает, если получатель метода не является вызываемой функцией. |
Примеры, попробуйте сами
Как сохранить this и первый аргумент
Измените объект контекста и привязанный аргумент. Посмотрите, какие значения использует новая функция.
index.html
<p>Результат выполнения выводится в консоль.</p>
main.js
let obj = {
// инициализируем переменную, содержащую объект
a: 100,
b: 200,
}
// функция возвращает сумму трех значений
let func = function (c) {
return this.a + this.b + c
}
// переменная содержит новую функцию, которая вызывается как метод объекта
let newFunc = func.bind(obj, 300)
console.log(newFunc()) // возвращаемое значение 600
В следующем примере мы создадим новую функцию путём фиксирования аргументов существующей (частичное применение). Каррирование — другой приём: преобразование функции в цепочку функций, принимающих аргументы по одному:
Как получить утроение из функции умножения
Замените привязанный множитель 3 другим числом и сравните результаты вызовов.
index.html
<p>Результат выполнения выводится в консоль.</p>
main.js
// функция возвращает произведение 2 аргументов
let multiply = function (a, b) {
return a * b
}
// создаем новую функцию, подобную multiply, но с контекстом равным null и первым аргументом равным 3
let triple = multiply.bind(null, 3)
// новая функция принимает один аргумент
console.log(triple(2)) // 6 (первый аргумент связан со значением 3, а значение 2 передается в качестве второго аргумента)
console.log(triple(3)) // 9 (первый аргумент связан со значением 3, а значение 3 передается в качестве второго аргумента)
console.log(triple(4)) // 12 (первый аргумент связан со значением 3, а значение 4 передается в качестве второго аргумента)
Почему new игнорирует привязанный this
Измените имя, переданное в bind(). Сравните новый экземпляр, неизменившийся объект контекста и ошибку при вызове связанной стрелки через new.
index.html
<p>Результат выполнения выводится в консоль.</p>
main.js
function Person(name) {
this.name = name
}
// bind() запоминает объект контекста и первый аргумент конструктора.
const context = { name: 'Исходный объект' }
const BoundPerson = Person.bind(context, 'Анна')
// new создаёт новый объект вместо использования привязанного context.
const person = new BoundPerson()
console.log('Имя нового объекта:', person.name) // Анна
console.log('Привязанный объект не изменился:', context.name) // Исходный объект
console.log('Это экземпляр Person:', person instanceof Person) // true
// Собственного prototype нет, но конструктором остаётся исходная Person.
console.log('Собственный prototype:', Object.hasOwn(BoundPerson, 'prototype')) // false
console.log('Прототип экземпляра:', Object.getPrototypeOf(person) === Person.prototype) // true
// Стрелка не может быть конструктором — bind() этого не меняет.
const arrow = (name) => ({ name })
const BoundArrow = arrow.bind(context, 'Анна')
try {
new BoundArrow()
} catch (error) {
console.log('new для связанной стрелки:', error.name) // TypeError
}