--- title: Function.prototype.bind() slug: Web/JavaScript/Reference/Global_Objects/Function/bind translation_of: Web/JavaScript/Reference/Global_Objects/Function/bind ---
O método bind() cria uma nova função que, quando chamada, tem sua palavra-chave this definida com o valor fornecido, com uma sequência determinada de argumentos precedendo quaisquer outros que sejam fornecidos quando a nova função é chamada.
{{EmbedInteractiveExample("pages/js/function-bind.html", "taller")}}
function.bind(thisArg[, arg1[, arg2[, ...]]])
thisArgthis para a função de destino quando a função vinculada é chamada. O valor é ignorado se a função ligada é construída usando o operador {{jsxref("Operators/new", "new")}}.arg1, arg2, ...Uma cópia da função fornecida com o valor this especificado e argumentos iniciais.
A função bind() cria uma nova função vinculada (bound function). Uma função vinculada é um objeto de função exótico (termo da ECMAScript 2015) que encapsula o objeto de função original. Chamar uma função vinculada geralmente resulta na execução de sua função encapsulada.
Uma função vinculada tem as seguintes propriedades internas:
this quando se chama a função encapsulada;this e uma lista contendo os argumentos passados para a função por uma expressão de chamada.Quando a função vinculada é chamada, ela chama seu método interno [[Call]] na [[BoundTargetFunction]], na forma Call(boundThis, args), onde boundThis é [[BoundThis]] e args é [[BoundArguments]] seguido pelos argumentos passados pela chamada de função.
Uma função vinculada também pode ser construída usando-se o operador {{jsxref("Operators/new", "new")}}; ao fazê-lo, o resultado é o mesmo que seria se a função alvo tivesse sido construída. O valor de this fornecido é ignorado, porém os argumentos precedentes são fornecidos à função emulada.
O uso mais simples de bind() é fazer com que uma função que, independentemente da chamada, é chamada com um determinado valor this. Um erro comum para programadores JavaScript novatos é extrair um método de um objeto e, em seguida, chamar essa função e esperar que ele use o objeto original como o seu this (por exemplo, usando esse método num código baseado em callback). Sem a devida atenção, no entanto, o objeto original é normalmente perdido. Criar uma função vinculada a partir da função, usando o objeto original, resolve perfeitamente esse problema:
this.x = 9; //this aqui se refere ao objeto global "window" do navegador
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX();
// retorna 9 - a função foi invocada no escopo global
// Criando uma nova função com 'this' vinculada ao módulo
// Programadores novatos podem confundir a variável x
// global com a propriedade x do módulo
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
O próximo uso mais simples de bind() é criar uma função com argumentos iniciais pré-especificados. Esses argumentos (caso existam) acompanham o valor this fornecido e então são inseridos no início dos argumentos passados para a função alvo, seguidos pelos argumentos passados para a função vinculada, sempre que a função vinculada é chamada.
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
// Cria uma função com um argumento principal predefinido
var leadingThirtysevenList = list.bind(null, 37);
var list2 = leadingThirtysevenList();
// [37]
var list3 = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]
setTimeoutPor padrão, dentro de {{domxref("window.setTimeout()")}} a palavra-chave this vai ser definida com o objeto {{ domxref("window") }} (ou com o objeto global). Ao trabalhar com métodos de classes que requerem que this se refira à instâncias de classes, você pode vincular this explicitamente à função de callback, de modo a manter a instância.
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// Declarar bloom depois de um intervalo de 1 segundo
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
};
var flower = new LateBloomer();
flower.bloom();
// depois de 1 segundo, ativa o método 'declare'
Aviso: Esta seção demonstra capacidades do JavaScript e documenta alguns casos de borda do método bind(). Os métodos mostrados abaixo não são os melhores jeitos de se fazer as coisas e provavelmente não deveriam ser usados em nenhum ambiente produtivo.
Funções vinculadas são automaticamente adequadas para uso com o operador {{jsxref("Operators/new", "new")}} para construir novas instâncias criadas pela função alvo. Quando uma função vinculada é usada para construir um valor, o this fornecido é ignorado. Porém, argumentos fornecidos ainda são prefixados à chamada do construtor:
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'
// não suportado no polyfill abaixo,
// funciona bem com o bind nativo:
var YAxisPoint = Point.bind(null, 0/*x*/);
var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0/*x*/);
var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'
axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new Point(17, 42) instanceof YAxisPoint; // true
Note que você não precisa fazer nada de especial para criar uma função vinculada para usar com {{jsxref("Operators/new", "new")}}. O corolário é que você não precisa fazer nada de especial para criar uma função vinculada que será chamada de forma clara, mesmo que você preferisse que a função vinculada fosse somente chamada usando-se {{jsxref("Operators/new", "new")}}.
// Exemplo pode ser executado diretamente no seu console JavaScript // ...continuando o exemplo acima // Ainda pode ser chamada como uma função normal // (apesar de que isso geralmente não é desejado) YAxisPoint(13); emptyObj.x + ',' + emptyObj.y; // > '0,13'
Se você quer suportar o uso de uma função vinculada somente através de {{jsxref("Operators/new", "new")}}, ou somente a chamando, a função alvo deve impor essa restrição.
bind() itambém é útil em casos onde você quer criar um atalho para uma função que requer um valor específico de this.
Tome por exemplo {{jsxref("Array.prototype.slice")}}, que você quer usar para converter um objeto array-like em um vetor verdadeiro. Você poderia criar um atalho assim:
var slice = Array.prototype.slice; // ... slice.apply(arguments);
Com bind(), isso pode ser simplificado. No seguinte trecho de código, slice é uma função vinculada à função {{jsxref("Function.prototype.apply()", "apply()")}} de {{jsxref("Function.prototype")}}, com o valor this definido com a função {{jsxref("Array.prototype.slice()", "slice()")}} de {{jsxref("Array.prototype")}}. Isso significa que chamadas adicionais de apply() podem ser eliminadas:
// mesmo que "slice" no exemplo anterior var unboundSlice = Array.prototype.slice; var slice = Function.prototype.apply.bind(unboundSlice); // ... slice(arguments);
A função bind é uma adição à ECMA-262, 5ª. edição; como tal, pode não estar presente em todos os navegadores. Você pode contornar isso parcialmente inserindo o seguinte código no começo de seus scripts, permitindo o uso de muita parte da funcionalidade de bind() em implementações que não a suportam nativamente.
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// mais próximo possível da função interna
// IsCallable da 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
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
Algumas das muitas diferenças (é bem possível que haja outras, já que esta lista não pretende seriamente ser completa) entre este algoritmo e o algoritmo especificado são:
arguments que lançam um {{jsxref("Global_Objects/TypeError", "TypeError")}} ao usar get, set, ou ao deletar. (Isto pode ser adicionado se a implementação suporta {{jsxref("Object.defineProperty")}}, ou parcialmente implementado sem um comportamento throw-on-delete se a implementação suporta as extensões {{jsxref("Object.defineGetter", "__defineGetter__")}} e {{jsxref("Object.defineSetter", "__defineSetter__")}})prototype. (Funções vinculadas apropriadas não a tem.)Se você escolher utilizar esta implementação parcial, você não deve confiar em casos onde o comportamento é diferente da ECMA-262, 5ª. edição! Porém, com algum cuidado (e talvez com modificação adicional para atender necessidades específicas), esta implementação parcial pode ser uma ponte razoável para quando bind() for amplamente implementada de acordo com a especificação.
| Especificação | Status | Comentário |
|---|---|---|
| {{SpecName('ES5.1', '#sec-15.3.4.5', 'Function.prototype.bind')}} | {{Spec2('ES5.1')}} | Definição inicial. Implementada no JavaScript 1.8.5. |
| {{SpecName('ES6', '#sec-function.prototype.bind', 'Function.prototype.bind')}} | {{Spec2('ES6')}} |
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Basic support | {{CompatChrome("7")}} | {{CompatGeckoDesktop("2")}} | {{CompatIE("9")}} | {{CompatOpera("11.60")}} | {{CompatSafari("5.1")}} |
| Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | {{CompatAndroid("4.0")}} | {{CompatChrome("1")}} | {{CompatGeckoMobile("2")}} | {{CompatUnknown}} | {{CompatOperaMobile("11.5")}} | {{CompatSafari("6.0")}} |