Em Javascript, como posso vincular argumentos a uma função sem vincular o this
parâmetro?
Por exemplo:
//Example function.
var c = function(a, b, c, callback) {};
//Bind values 1, 2, and 3 to a, b, and c, leave callback unbound.
var b = c.bind(null, 1, 2, 3); //How can I do this without binding scope?
Como posso evitar o efeito colateral de ter que vincular o escopo da função (por exemplo, configuração this
= nulo) também?
Editar:
Desculpe pela confusão. Quero vincular argumentos e, em seguida, ser capaz de chamar a função vinculada mais tarde e fazer com que ela se comporte exatamente como se eu chamasse a função original e passasse os argumentos vinculados:
var x = 'outside object';
var obj = {
x: 'inside object',
c: function(a, b, c, callback) {
console.log(this.x);
}
};
var b = obj.c.bind(null, 1, 2, 3);
//These should both have exact same output.
obj.c(1, 2, 3, function(){});
b(function(){});
//The following works, but I was hoping there was a better way:
var b = obj.c.bind(obj, 1, 2, 3); //Anyway to make it work without typing obj twice?
Ainda sou novo nisso, desculpe a confusão.
Obrigado!
javascript
Imbuir
fonte
fonte
this
?var b = c.bind(this, 1,2,3);
bind()
sernull
? Parece funcionar bem no FF.this
totalmente desvinculado do JavaScript. Sempre significa alguma coisa . Portanto, vincularthis
aothis
da função envolvente faz muito sentido.Respostas:
Você pode fazer isso, mas é melhor evitar pensar nisso como "vinculação", pois esse é o termo usado para definir o valor "this". Talvez pense nisso como "agrupar" os argumentos em uma função?
O que você faz é criar uma função que tenha os argumentos desejados incorporados por meio de encerramentos:
Espero ter conseguido a sintaxe certa. O que ele faz é criar uma função chamada withWrappedArguments () (para ser pedante, é uma função anônima atribuída à variável) que você pode chamar a qualquer momento em qualquer lugar e sempre agirá com actualArg1Value e realArg2Value, e qualquer outra coisa que você queira inserir há. Você também pode fazer com que ele aceite outros argumentos no momento da chamada, se desejar. O segredo são os parênteses após a chave de fechamento final. Isso faz com que a função externa seja executada imediatamente, com os valores passados, e gere a função interna que pode ser chamada posteriormente. Os valores passados são congelados no momento em que a função é gerada.
Isso é efetivamente o que o bind faz, mas desta forma é explícito que os argumentos encapsulados são simplesmente encerramentos em variáveis locais, e não há necessidade de alterar o comportamento disso.
fonte
f(x,y)
queremosf(x)(y)
oug=f(x); g(y)
. Portanto, mudaríamosf=(x,y)=>x+y
paraf=(x)=>(y)=>x+y
."No ES6, isso é feito facilmente usando parâmetros de descanso em conjunto com o operador de espalhamento .
Portanto, podemos definir uma função
bindArgs
que funciona comobind
, exceto que apenas os argumentos são vinculados, mas não o contexto (this
).Então, para uma função especificada
foo
e um objetoobj
, a instruçãoé equivalente a
onde apenas o primeiro e o segundo argumentos são vinculados
bar
, enquanto o contextoobj
especificado na invocação é usado e argumentos extras são acrescentados após os argumentos vinculados. O valor de retorno é simplesmente encaminhado.fonte
let
econst
, ainda não estavam disponíveis quando eu postei isto pela primeira vez. Ele está atualizado agora.No
bind
método nativo , othis
valor na função de resultado é perdido. No entanto, você pode facilmente recodificar o shim comum para não usar um argumento para o contexto:fonte
Function
mas me economizou muito tempo e algumas soluções alternativas. Obrigadobind
. Você pode facilmente transformá-lo em umfunction bindArgs(fn){ …, args = slice.call(arguments, 1); …}
this
sera
. Você pode usar embind
vez disso, é claro. No entanto, o OP explicitamente não se preocupa com othis
valor e deseja uma função parcial não vinculada.this
é que a função usathis
, mas eles não queriam vinculá-la naquele momento. Além disso, a parte na pergunta do OP//These should both have exact same output.
é contraditória com outras partes dele.bind
não funciona com construtores, as funções associadas não têm.prototype
. Não,Function.prototype !== mymethod.prototype
Mais uma pequena implementação apenas por diversão:
Como usar:
fonte
fonte
const curry = (fn, ...curryArgs) => (...args) => fn(...curryArgs, args)
É um pouco difícil dizer exatamente o que você quer fazer porque o exemplo é meio arbitrário, mas você pode querer dar uma olhada em parciais (ou currying): http://jsbin.com/ifoqoj/1/edit
Link para o artigo de John Resig: http://ejohn.org/blog/partial-functions-in-javascript/
fonte
partial
precisa ser chamado comundefined
argumentos para funcionar - não o que se esperaria, e interrompido em funções que usam um número arbitrário de parâmetros.this
objeto ainda fica bagunçado. Dê uma olhada em: jsbin.com/ifoqoj/4/editPode ser que você queira vincular a referência deste no último, mas seu código: -
Já aplicou vinculação por exemplo esta e posteriormente você não pode alterá-la. O que vou sugerir é que use a referência também como um parâmetro como este: -
fonte
Use um
protagonist
!Basicamente, a função para a qual você deseja passar parâmetros se torna um proxy que você pode chamar para passar uma variável, e retorna a função que você realmente deseja fazer.
Espero que isto ajude!
fonte
Um usuário anônimo postou esta informação adicional:
fonte
Bem, para o exemplo que você deu, isso servirá
Se você deseja garantir o fechamento dos parâmetros:
Mas se for assim, você deve apenas se ater à sua solução:
É a melhor maneira.
fonte
Simples assim?
Solução mais geral:
fonte
Usando o LoDash, você pode usar a
_.partial
função.fonte
Por que não usar um invólucro em torno da função para salvá-la como mythis?
fonte
O jQuery 1.9 trouxe exatamente esse recurso com a função proxy.
Exemplo:
fonte
Caso de uso do Jquery:
em vez de:
usa isto:
fonte