2017-08-11 2 views
3

La méthode de liaison de Javascript ne fonctionne pas comme prévu

var obj = { 
 
    say: function() { 
 
     function _say() { 
 
      console.log(this); 
 
     } 
 
     return _say.bind(obj); 
 
    }() 
 
}; 
 

 
obj.say();

le résultat de code est log le global ou la fenêtre, je veux savoir pourquoi la méthode de liaison ne lie pas « ceci » au contexte d'objet obj?

+0

La vraie question ici est de savoir si vous avez besoin de cette liaison, pourquoi n'utilisez-vous pas un objet-avec-prototype? Le code que vous montrez essaie de passer de la "logique d'instance" au code "instance-of-nothing", ce que vous pouvez * faire *, c'est JavaScript, mais c'est aussi vraiment ... idiot? Qu'est-ce que vous * essayez * de faire avec ce code? (ou avec un code comme celui-ci) –

+0

(1) Placez un point d'arrêt sur la ligne 'return _say.bind (obj); (2) Quand il s'arrête là, examinez la valeur de 'obj'. (3) Pensez vraiment dur. (4) Expliquez à votre [canard en caoutchouc] (https://en.wikipedia.org/wiki/Rubber_duck_debugging) exactement pourquoi vous essayez d'assigner le résultat d'un IIFE à la propriété 'say'. –

+0

Merci pour vos commentaires, @Mike 'Pomax' Kamermans. Ce code est une pratique juste, je veux savoir pourquoi 'this' est global quand on utilise bind (undefined). – smallbone

Répondre

1

Pendant l'affectation de la variable obj ne dispose toujours pas de valeur. En tant que tel, votre appel à lier est équivalent à .bind(undefined) qui se comporte comme vous l'avez observé.

Pour être plus précis, this se référant à window est en raison de OrdinaryCallBindThis faire les étapes suivantes (mode non stricte):

[...] 
If thisArgument is undefined or null, then 
[...] 
Let thisValue be globalEnvRec.[[GlobalThisValue]]. 

Vous pouvez vérifier dans le débogueur de chrome qui [[BoundThis]] est en effet undefined après votre appel.

+0

Merci pour votre réponse, @ASDGerte. Mais si la fonction _say lie 'this' à 'undefined', pourquoi le 'this' dans obj.say() se lie à global/window au lieu de obj? – smallbone

+0

@smallbone édité. Je cherchais juste cela après avoir répondu aussi :) – ASDFGerte

+0

Je l'ai eu! Merci beaucoup. – smallbone

0

Vous appelez la fonction immédiatement. Supprimer les parenthèses suivant la fonction say. Si vous prévoyez d'appeler la fonction sans deux parenthèses consécutives obj.say()() utilisation .call() au lieu de .bind()

var obj = { 
 
    say: function() { 
 
    function _say() { 
 
     console.log(this); 
 
    } 
 
    return _say.call(this); 
 
    } 
 
}; 
 

 
obj.say();