Maison > interface Web > js tutoriel > Discutez de la fonction bind() en javascript

Discutez de la fonction bind() en javascript

coldplay.xixi
Libérer: 2020-06-15 16:25:00
avant
2084 Les gens l'ont consulté

Discutez de la fonction bind() en javascriptComprendre la fonction bind() en javascript

Partager :

La méthode bind() créera une nouvelle fonction , Lorsque cette nouvelle fonction est appelée, sa valeur this est le premier paramètre passé à bind(), et ses paramètres sont les autres paramètres de bind() et ses paramètres d'origine.

La syntaxe est la suivante :

fun.bind(thisArg[, arg1[, arg2[, ...]]])
Copier après la connexion

thisArg Lorsque la fonction liée est appelée, ce paramètre sera utilisé comme pointeur this de la fonction d'origine lors de son exécution. Ce paramètre n'a aucun effet lors de l'appel de la fonction liée à l'aide de l'opérateur new.

arg1, arg2, … (facultatif) Lorsque la fonction liée est appelée, ces paramètres ainsi que les paramètres de la fonction liée elle-même seront utilisés dans l'ordre comme paramètres de la fonction d'origine lors de son exécution.

Paramètres

Le premier paramètre de bind sera utilisé comme ce pointeur lorsque la fonction d'origine est en cours d'exécution, pas grand chose à dire et le deuxième paramètre de départ est facultatif, lorsque la fonction liée est appelée, ces paramètres ainsi que les paramètres de la fonction liée elle-même seront utilisés comme paramètres de la fonction d'origine lors de l'exécution dans l'ordre. Comment comprendre ? La fonction

function fn(a, b, c) {
  return a + b + c;
}
var _fn = fn.bind(null, 10);
var ans = _fn(20, 30); // 60
Copier après la connexion

fn nécessite trois paramètres. La fonction _fn utilise 10 comme premier paramètre par défaut, vous n'avez donc besoin de transmettre que deux paramètres. Si vous transmettez accidentellement trois paramètres, ne vous inquiétez pas. les deux premiers seront pris.

function fn(a, b, c) {
  return a + b + c;
}
var _fn = fn.bind(null, 10);
var ans = _fn(20, 30, 40); // 60
Copier après la connexion

A quoi ça sert ? Si les premiers paramètres de certaines fonctions ont été « par défaut », nous pouvons utiliser bind pour renvoyer une nouvelle fonction. En d’autres termes, bind() permet à une fonction d’avoir des paramètres initiaux prédéfinis. Ces arguments (le cas échéant) suivent ceci comme deuxième argument de bind(). Ils sont ensuite insérés au début de la liste d'arguments de la fonction cible, et les arguments passés à la fonction liée les suivent.

function list() {
  return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);
var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
Copier après la connexion

new

Le résultat renvoyé par bind est toujours une fonction Si c'est une fonction, elle peut être appelée par l'opérateur new. La spécification indique très clairement que lorsque l'opérateur new est utilisé pour appeler une fonction liée, le premier paramètre de bind n'est pas valide.

function Person(name, age) {
  this.name = name;
  this.age = age;
}
var _Person = Person.bind({});
var p = new _Person('hanzichi', 30); // Person {name: "hanzichi", age: 30}
Copier après la connexion

Généralement, nous ne l'utilisons pas de cette façon, mais si vous souhaitez écrire un polyfill de liaison (http://caniuse.com/#search=bind), vous devez toujours envisager d'utiliser new pour appeler il.

Nous pouvons également définir des valeurs par défaut (voir la section précédente), et les paramètres initialement fournis seront toujours ajoutés au début de l'appel du constructeur.

function Person(name, age) {
  this.name = name;
  this.age = age;
}
var _Person = Person.bind(null, 'hanzichi');
var p = new _Person(30); // Person {name: "hanzichi", age: 30}
Copier après la connexion

Avec setTimeout

Quand est-il facile de perdre ce pointeur ? Eh bien, setTimeout est une scène, et il est facile de la pointer vers la fenêtre. Bien sûr, la même chose est vraie pour setInterval. Lorsque vous utilisez les méthodes d'un objet, qui nécessitent que this fasse référence à l'objet, vous devrez peut-être le lier explicitement à la fonction de rappel afin de continuer à utiliser l'objet.

var canvas = {
  render: function() {
    this.update();
    this.draw();
  },
  update: function() {
    // ...
  },
  draw: function() {
    // ...
  }
};
window.setInterval(canvas.render, 1000 / 60);
Copier après la connexion

Nous rencontrons souvent des problèmes similaires lorsque nous utilisons Canvas pour écrire des effets spéciaux ou créer des jeux. Il y a un problème avec le code ci-dessus. Dans la méthode de rendu, il pointe en fait vers la fenêtre ! Nous pouvons utiliser bind pour lier explicitement cela à la fonction de rappel afin que nous puissions continuer à utiliser l'objet.

window.setInterval(canvas.render.bind(canvas), 1000);
Copier après la connexion

Une situation similaire est la surveillance des événements de dom. Si vous ne faites pas attention, cela peut être pointé vers l'élément dom. Vous pouvez vous référer à cette partie du code écrit lorsque vous travaillez sur bigrender avant https://github.com/hanzichi/hanzichi.github.io/blob/master/2016/bigrender/js/bigrender.js#L179-L184.

astuce

bind peut aussi faire des choses intéressantes.

De manière générale, pour convertir un objet de type tableau en tableau, nous utilisons slice (non pris en charge par ie9-). Référence #14

var slice = Array.prototype.slice;
// slice.apply(arguments);
// slice(arguments, 1);
bind 能让调用变的更加简单。
// same as "slice" in the previous example
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);
// ...
slice(arguments);
// slice(arguments, 1);
Copier après la connexion

Pour un autre exemple similaire, par exemple, si l'on veut ajouter des événements à plusieurs nœuds, bien sûr il n'y a aucun problème avec la boucle for On peut aussi "plagier" la méthode forEach :

Array.prototype.forEach.call(document.querySelectorAll('input[type="button"]'), function(el){
  el.addEventListener('click', fn);
});
Copier après la connexion

De plus, nous pouvons utiliser bind pour mieux encapsuler la fonction :

var unboundForEach = Array.prototype.forEach
  , forEach = Function.prototype.call.bind(unboundForEach);
forEach(document.querySelectorAll('input[type="button"]'), function (el) {
  el.addEventListener('click', fn);
});
Copier après la connexion

De même, nous pouvons changer x.y(z) sous la forme y(x,z) :

var obj = {
  num: 10,
  getCount: function() {
    return this.num;
  }
};
var unboundBind = Function.prototype.bind
  , bind = Function.prototype.call.bind(unboundBind);
var getCount = bind(obj.getCount, obj);
console.log(getCount());  // 10
Copier après la connexion

Donnez un autre exemple. Imprimer 1 à 5 sur la console chaque seconde semble être un problème classique lors de l'examen des fermetures.

for(var i = 1; i <= 5; i++) {
  !function(i) {
    setTimeout(function() {
      console.log(i);
    }, i * 1000);
  }(i);
}
Copier après la connexion

Vous pouvez utiliser let sous ES6 :

for(let i = 1; i <= 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}
Copier après la connexion

Vous pouvez également utiliser bind pour améliorer instantanément vos performances :

for(var i = 1; i <= 5; i++) {
  setTimeout(console.log.bind(console, i), i * 1000);
}
Copier après la connexion

Tutoriel recommandé : "Tutoriel de base js

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:webhek.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal