43 votes

Que signifie " lier."lient" signifie? Une bien étrange façon d'utiliser le JavaScript lier

Je suis en train de lire un livre sur l'écriture de frameworks JavaScript et trouvé ce bout de code. Mais je ne comprends pas comment il fonctionne, en particulier l' bind.bind d'utilisation? Quelqu'un a une idée?

var bind = Function.prototype.bind;
var apply = bind.bind(bind.apply);
var fn = apply([].concat);
var a = [1, 2, 3], b = [4, [5, 6], 7];
fn(a, b);
//output [1, 2, 3, 4, 5, 6, 7]

35voto

elpd Points 38

Cela me ramène à l'époque de la résolution et de l'expansion des équations.

1 . Tout d'abord, permet de développer la première application de fonction:

var bind = Function.prototype.bind;
var apply = bind.bind(bind.apply);
var fn = apply([].concat);

Transformations:

var apply = Function.prototype.bind.bind(Function.prototype.bind.apply);
var fn = apply([].concat)

2 . Deuxièmement, nous étendons la fonction fn:

var fn = Function.prototype.bind.bind(Function.prototype.bind.apply)([].concat);

3 . Nous avons maintenant inventer un js de l'algèbre à la règle et remplacer l' bind.bind...() invocation à l'appel de son invocation.

En fait, nous de mettre en œuvre une base de remplacement sur l'idée que:

someFunction.bind(arg1)(arg2) <==> someFunction.call(arg1, arg2)

Par conséquent, nous pouvons la remplacer et obtenez:

var fn = Function.prototype.bind.call(Function.prototype.bind.apply, [].concat);

4 . Pour notre deuxième js algèbre règle que nous concevons que:

someFn.bind.call(target, ...) <==> target.bind(...).

someFn n'est pas important ici, car nous ne les appelons pas bind() sur celui-ci. Nous invoquons call sur le bind - remplacement de l' this qui a someFn et à cet effet, il est remplacé par target.

Par conséquent, nous remplaçons l' bind.call(target) avec la cible.lier alternative

var fn = Function.prototype.bind.apply.bind([].concat) 

5 . Si la dernière permutation a été également faire l'invocation (), nous l'aurions fait un remplacement comme:

fn([1, 2], [3, 4]) <==> [].concat.apply([1, 2], [3, 4])

Mais nous n'avons que la liaison sans l'invocation, qui nous permet de remplacer et est équivalent à:

var fn = function (arg1, arg2) { 
    return [].concat.apply(arg1, arg2); 
}
// instead arg1 and arg2 we could use more accurate arguments logic also.

Résultat Final

var fn = Function.prototype.bind.apply.bind([].concat) 

// or

var fn = function (arg1, arg2) { 
    return [].concat.apply(arg1, arg2); 
}

L' fn fonction prend l' concat de la fonction et nous permet de nous dans un style fonctionnel, sans l'appeler à partir d'un objet. Au lieu de concat lié à l' this de l'appelant, fn s'applique sur arg1 comme this et arg2 comme les autres params à la concaténation d' arg1.

fn([1, 2], [3, [5, 6], 4])
// [1, 2, 3, 5, 6, 4]

12voto

djfdev Points 128

Parce qu' Function.prototype.bind est lui-même une fonction, elle hérite de lui-même comme une méthode.

Généralement, la liaison est appelée comme une méthode d'instance d'une fonction particulière, mais nous pouvons nous relier à d' Function.prototype.apply et le retour d'une fonction d'ordre supérieur.

Moins laconique moyen de l'écriture, ce serait:

function apply (fn) {
  return function (a, b) {
    return fn.apply(a, b)
  }
}

3voto

Neil Points 24938

Nous avons à réfléchir un peu sur ce qu' bind ne fait coulisses. Pour une approximation, il fonctionne comme ceci:

function bind(fn, ...bound) {
    return (...other) => this.call(fn, ...bound, ...other);
}

(Rappelez-vous que le lexique this fait référence à la fonction qui bind est appelé.) Donc, en prenant

apply = bind.bind(bind.apply);

et manuellement développant bind nous-mêmes, nous obtenons:

apply = (...other) => bind.call(bind.apply, ...other);

Nous sommes seulement intéressés par le passage d'un seul argument, qui est une fonction. J'espère que cela signifie aussi que ses apply de la propriété est la même que celle de l' bind:

apply = (fn) => bind.call(fn.apply, fn);

Mais bind est (espérons-le), elle aussi, sur fn.applys'prototype, nous pouvons simplifier en outre à:

apply = (fn) => fn.apply.bind(fn);

Nous sommes maintenant dans une position pour développer bind nouveau:

apply = (fn) => (...other) => fn.apply.call(fn, ...other);

Cette fois, nous voulons deux arguments, et l'appel à l' call peut également être simplifiée:

apply = (fn) => (obj, args) => fn.apply(obj, args);

Nous sommes maintenant en mesure d'invoquer apply sur [].concat:

fn = (obj, args) => [].concat.apply(obj, args);

obj doit être un tableau pour que cela fonctionne, donc cela se simplifie en:

fn = (obj, args) => obj.concat(...args);

Et dans l'exemple fourni par nous jusqu'à la fin avec

[1, 2, 3].concat(4, [5, 6], 7)

qui retourne le résultat attendu.

2voto

Anil Kumar Points 1546

bind() méthode crée une nouvelle instance de la fonction à la valeur passée en bind().

Ici, nous appelons Function.prototype.bind.apply(Function.prototype, [null].concat(arguments)); par effraction dans exécutable séparé des unités de code.

L'objectif est d'appeler apply; pour passer de la fonction d'origine comme le premier param puis tableau d'arguments.

Ce codes a différentes variables pour chaque processus pour parvenir à se lier avec une dynamique params.

var bind=Function.prototype.bind; 
  // the bind function is assigned to a var

var apply=bind.bind(bind.apply); 
  // a new function apply is created which is nothing but bind.apply

var fn=apply([].concat); 
  // the apply function is defined and now we have final function 
   that will concat array.

Les deux dernières lignes sont pour l'exécution de l' fn fonction en passant deux paramètres

var a=[1,2,3],b=[4,[5,6],7]; fn(a,b);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X