Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Эта страница была переведена с английского языка силами сообщества. Вы тоже можете внести свой вклад, присоединившись к русскоязычному сообществу MDN Web Docs.

Function.prototype.bind()

BaselineWidely available

Сводка

Методbind() создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполненияthis предоставленное значение. В метод также передаётся набор аргументов, которые будут установлены перед переданными в привязанную функцию аргументами при её вызове.

Синтаксис

fun.bind(thisArg[, arg1[, arg2[, ...]]])

Параметры

thisArg

Значение, передаваемое в качествеthis в целевую функцию при вызове привязанной функции. Значение игнорируется, если привязанная функция конструируется с помощью оператораnew.

arg1, arg2, ...

Аргументы целевой функции, передаваемые перед аргументами привязанной функции при вызове целевой функции.

Описание

Методbind() создаёт новую "привязанную функцию" (ПФ).ПФ - это "необычный функциональный объект" ( термин изECMAScript 6 ), который является обёрткой над исходным функциональным объектом. ВызовПФ приводит к исполнению кода обёрнутой функции.

ПФ имеет следующие внутренние ( скрытые ) свойства:

  • [[BoundTargetFunction]] - оборачиваемый (целевой ) функциональный объект
  • [[BoundThis]] - значение, которое всегда передаётся в качестве значенияthis при вызове обёрнутой функции.
  • [[BoundArguments]] - список значений, элементы которого используются в качестве первого аргумента при вызове оборачиваемой функции.
  • [[Call]] - внутренний метод. Выполняет код (функциональное выражение), связанный с функциональным объектом.

КогдаПФ вызывается, исполняется её внутренний метод[[Call]] со следующими аргументамиCall(target,boundThis,args).

  • target -[[BoundTargetFunction]];
  • boundThis -[[BoundThis]];
  • args -[[BoundArguments]].

Привязанная функция также может быть сконструирована с помощью оператораnew: это работает так, как если бы вместо неё конструировалась целевая функция. Предоставляемое значениеthis в этом случае игнорируется, хотя ведущие аргументы всё ещё передаются в эмулируемую функцию.

Примеры

Пример: создание привязанной функции

Простейшим способом использованияbind() является создание функции, которая, вне зависимости от способа её вызова, вызывается с определённым значениемthis. Обычным заблуждением для новичков в JavaScript является извлечение метода из объекта с целью его дальнейшего вызова в качестве функции и ожидание того, что он будет использовать оригинальный объект в качестве своего значенияthis (например, такое может случиться при использовании метода как колбэк-функции). Однако, без специальной обработки, оригинальный объект зачастую теряется. Создание привязанной функции из функции, использующей оригинальный объект, изящно решает эту проблему:

js
this.x = 9;var module = {  x: 81,  getX: function () {    return this.x;  },};module.getX(); // 81var getX = module.getX;getX(); // 9, поскольку в этом случае this ссылается на глобальный объект// создаём новую функцию с this, привязанным к modulevar boundGetX = getX.bind(module);boundGetX(); // 81

Пример: частичные функции

Следующим простейшим способом использованияbind() является создание функции с предопределёнными аргументами. Эти аргументы (если они есть) передаются после значенияthis и вставляются перед аргументами, передаваемыми в целевую функцию при вызове привязанной функции.

js
function list() {  return Array.prototype.slice.call(arguments);}var list1 = list(1, 2, 3); // [1, 2, 3]// Создаём функцию с предустановленным ведущим аргументомvar leadingThirtysevenList = list.bind(undefined, 37);var list2 = leadingThirtysevenList(); // [37]var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]

Пример: сsetTimeout

По умолчанию, внутриwindow.setTimeout() контекстthis устанавливается в объектwindow (илиglobal). При работе с методами класса, требующимиthis для ссылки на экземпляры класса, вы можете явно привязатьthis к колбэк-функции для сохранения экземпляра.

js
function LateBloomer() {  this.petalCount = Math.ceil(Math.random() * 12) + 1;}// Объявляем цветение с задержкой в 1 секундуLateBloomer.prototype.bloom = function () {  window.setTimeout(this.declare.bind(this), 1000);};LateBloomer.prototype.declare = function () {  console.log("Я прекрасный цветок с " + this.petalCount + " лепестками!");};

Пример: привязывание функций, используемых в качестве конструкторов

Предупреждение:Этот раздел демонстрирует возможности JavaScript и документирует некоторые граничные случаи использования методаbind(). Показанные ниже методы не являются лучшей практикой и, вероятно, их не следует использовать в рабочем окружении.

Привязанные функции автоматически подходят для использования вместе с операторомnew для конструирования новых экземпляров, создаваемых целевой функцией. Когда привязанная функция используется для конструирования значения, предоставляемое значениеthis игнорируется. Однако, предоставляемые аргументы всё так же вставляются перед аргументами конструктора:

js
function Point(x, y) {  this.x = x;  this.y = y;}Point.prototype.toString = function () {  return this.x + "," + this.y;};var p = new Point(1, 2);p.toString(); // '1,2'var emptyObj = {};var YAxisPoint = Point.bind(emptyObj, 0 /*x*/);// не поддерживается полифилом, приведённым ниже,// но отлично работает с родным bind:var YAxisPoint = Point.bind(null, 0 /*x*/);var axisPoint = new YAxisPoint(5);axisPoint.toString(); // '0,5'axisPoint instanceof Point; // trueaxisPoint instanceof YAxisPoint; // truenew Point(17, 42) instanceof YAxisPoint; // true

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

js
// Пример может быть запущен прямо в вашей консоли JavaScript// ...продолжение примера выше// Всё ещё можно вызывать как нормальную функцию// (хотя обычно это не предполагается)YAxisPoint(13);emptyObj.x + "," + emptyObj.y;// >  '0,13'

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

Пример: создание сокращений

Методbind() также полезен в случаях, если вы хотите создать сокращение для функции, требующей определённое значениеthis.

Возьмём, например, методArray.prototype.slice, который вы можете использовать для преобразования массивоподобного объекта в настоящий массив. Вы можете создать подобное сокращение:

js
var slice = Array.prototype.slice;// ...slice.call(arguments);

С помощью методаbind(), это сокращение может быть упрощено. В следующем куске кодаslice является функцией, привязанной к функцииcall() объектаFunction.prototype, со значениемthis, установленным в функциюslice() объектаArray.prototype. Это означает, что дополнительный вызовcall() может быть устранён:

js
// Тоже самое, что и slice в предыдущем примереvar unboundSlice = Array.prototype.slice;var slice = Function.prototype.call.bind(unboundSlice);// ...slice(arguments);

Полифил

Функцияbind является дополнением к стандарту ECMA-262 5-го издания; поэтому она может присутствовать не во всех браузерах. Вы можете частично обойти это ограничение, вставив следующий код в начало ваших скриптов, он позволяет использовать большую часть возможностейbind() в реализациях, не имеющих его родной поддержки.

js
if (!Function.prototype.bind) {  Function.prototype.bind = function (oThis) {    if (typeof this !== "function") {      // ближайший аналог внутренней функции      // IsCallable в ECMAScript 5      throw new TypeError(        "Function.prototype.bind - what is trying to be bound is not callable",      );    }    var aArgs = Array.prototype.slice.call(arguments, 1),      fToBind = this,      fNOP = function () {},      fBound = function () {        return fToBind.apply(          this instanceof fNOP && oThis ? this : oThis,          aArgs.concat(Array.prototype.slice.call(arguments)),        );      };    fNOP.prototype = this.prototype;    fBound.prototype = new fNOP();    return fBound;  };}

Некоторые из многих отличий (так же могут быть и другие, данный список далеко не исчерпывающий) между этой реализацией и реализацией по умолчанию:

  • Частичная реализация предполагает, что методыArray.prototype.slice(),Array.prototype.concat(),Function.prototype.call() иFunction.prototype.apply() являются встроенными, имеют своё первоначальное значение.
  • Частичная реализация создаёт функции, не имеющие неизменяемых свойств «отравленной пилюли» —caller иarguments — которые выбрасывают исключениеTypeError при попытке получить, установить или удалить эти свойства. (Такие свойства могут быть добавлены, если реализация поддерживаетObject.defineProperty, либо частично реализованы [без поведения исключение-при-попытке-удаления], если реализация поддерживает расширенияObject.prototype.__defineGetter__() иObject.prototype.__defineSetter__().)
  • Частичная реализация создаёт функции, имеющие свойствоprototype. (Правильная привязанная функция его не имеет.)
  • Частичная реализация создаёт привязанные функции, чьё свойствоlength не соответствует с определением в ECMA-262; оно равно 0, в то время, как полная реализация, в зависимости от значения свойстваlength целевой функции и количества предопределённых аргументов, может вернуть значение, отличное от нуля.

Если вы решили использовать частичную реализацию,не рассчитывайте на корректную работу в тех случаях, когда реализация отклоняется от спецификации ECMA-262 5-го издания! Однако, в определённых случаях (и, возможно, с дополнительными модификациями для отдельных нужд), применение данной частичной реализации может быть вполне оправданным до тех пор, покаbind() не станет широко реализован в соответствии со спецификацией.

Спецификации

Specification
ECMAScript® 2026 Language Specification
# sec-function.prototype.bind

Совместимость с браузерами

Смотрите также

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp