Lorsque nous apprenons Javascript pour la première fois, nous n'avons peut-être pas besoin de nous soucier de la liaison de fonction, mais lorsque nous devons maintenir l'objet contextuel this dans une autre fonction, nous rencontrerons des problèmes correspondants. J'ai vu beaucoup de gens faire face à tous ces problèmes. doivent d'abord attribuer this à une variable (telle que self, _this, that, etc.), en particulier var that = this est celle que je vois le plus, afin que vous puissiez l'utiliser après avoir changé d'environnement. Tout cela est possible, mais il existe une méthode meilleure et plus propriétaire, qui consiste à utiliser Function.prototype.bind, qui est expliquée en détail ci-dessous.
Partie 1 : Problèmes à résoudre
Regardez d'abord le code ci-dessous
var myObj = { specialFunction: function () { }, anotherSpecialFunction: function () { }, getAsyncData: function (cb) { cb(); }, render: function () { this.getAsyncData(function () { this.specialFunction(); this.anotherSpecialFunction(); }); } }; myObj.render();
Ici, je j'espère créer un objet, y compris les deux premières méthodes ordinaires ; la troisième méthode peut transmettre une fonction, et la fonction transmise sera exécutée immédiatement. La dernière méthode appellera la méthode getAsyncData de l'objet myObj, en l'utilisant ici, et puis en le passant dans la méthode getAsyncData En entrant dans une fonction, cette fonction continue d'appeler les deux premières méthodes de cet objet, toujours en l'utilisant. À ce moment, de nombreuses personnes peuvent réellement voir le problème. Entrez le code ci-dessus dans la console et obtenez le. résultat suivant :
TypeError: this.specialFunction is not a function
Partie 2 : Analyse du problème
Ceci dans la méthode de rendu de l'objet pointe vers l'objet myObj, nous pouvons donc l'appeler via this.getAsyncData La fonction dans l'objet, mais lorsque nous passons la fonction en tant que paramètre, cela pointe ici vers la fenêtre de l'environnement global. Étant donné que les deux premières méthodes de l'objet n'existent pas dans l'environnement global, une erreur est signalée.
Partie 3 : Plusieurs façons de résoudre le problème
Ce que nous devons donc faire est d'appeler correctement les deux premières méthodes de l'objet. La méthode utilisée par de nombreuses personnes consiste à appeler d'abord le. environnement de l'objet Obtenez ceci et affectez-le à une autre variable, vous pourrez ensuite l'appeler dans l'environnement suivant, comme indiqué ci-dessous :
render: function () { var that = this; this.getAsyncData(function () { that.specialFunction(); that.anotherSpecialFunction(); }); }
Bien que cette méthode soit réalisable, utilisez Function.prototype .bind() rendra le code plus clair et plus facile à comprendre, comme indiqué ci-dessous :
render: function () { this.getAsyncData(function () { this.specialFunction(); this.anotherSpecialFunction(); }.bind(this)); }
Ici, nous avons réussi à lier cela à l'environnement.
Ce qui suit est un autre exemple simple :
var foo = { x: 3 } var bar = function(){ console.log(this.x); } bar(); // undefined var boundFunc = bar.bind(foo); boundFunc(); // 3
L'exemple suivant est également courant :
this.x = 9; // this refers to global "window" object here in the browser var module = { x: 81, getX: function() { return this.x; } }; module.getX(); // 81 var retrieveX = module.getX; retrieveX(); // returns 9 - The function gets invoked at the global scope // Create a new function with 'this' bound to module // New programmers might confuse the // global var x with module's property x var boundGetX = retrieveX.bind(module); boundGetX(); // 81
Partie 4 : Prise en charge du navigateur
Mais cette méthode n'est pas prise en charge dans IE8 et versions antérieures, nous pouvons donc utiliser la méthode fournie par MDN pour permettre aux versions inférieures d'IE de prendre en charge le Méthode .bind() :
if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== "function") { // closest thing possible to the ECMAScript 5 internal IsCallable function 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; }; }
Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'apprentissage de chacun, et j'espère. vous en apprendrez plus. Supportez le site Web chinois PHP.
Pour plus d'articles sur la façon de comprendre Function.prototype.bind en javascript, veuillez faire attention au site Web PHP chinois !