Introduction
1. Type de référence
Le type de référence est un type interne en JavaScript. Il est principalement utilisé comme référence, en remplacement d'une variable ou d'une fonction. Bien entendu, lorsque la valeur réelle est nécessaire, la valeur réelle peut être trouvée grâce à elle.
2. Structure du type de référence
La valeur d'un type référence se compose de deux parties. L'une est l'objet auquel appartient l'objet référencé par la valeur du type référence, et l'autre est le nom de l'objet dans base. Représenté en pseudo code :
Copiez le code comme suit :
var valueOfReferenceType = {
base : <objet de base>,
propertyName : <nom de la propriété>
} ;
3. Scénarios d'utilisation
Il existe deux scénarios d'utilisation pour les types de référence :
(1) Lors du traitement d'un identifiant
Les identifiants sont des noms de variables, des noms de fonctions, des noms de paramètres de fonction et des noms de propriétés non reconnues dans les objets globaux.
(2) Lors du traitement d'un accesseur à la propriété
Copiez le code comme suit :
var foo = 10 ;
barre de fonctions( ){}
Dans les résultats intermédiaires de l'opération, le type de référence correspond à
Copiez le code comme suit :
var fooRéférence = {
base : mondiale,
nom de la propriété : 'foo'
} ;
var barRéférence = {
base : mondiale,
nom de la propriété : 'bar'
} ;
Encore faut-il expliquer ici la base. En JavaScript, tous les objets ou fonctions ont leurs propres objets. Quiconque a lu mon article précédent sait qu'il existe un objet variable dans chaque contexte d'exécution pour gérer les variables ou fonctions dans ce contexte d'exécution. .
Ainsi, lorsqu’il s’agit d’identifiants :
Dans le contexte global, il va de soi que base === globalVO === gloabal
Dans le contexte d'exécution de la fonction, base === VO/AO
Mais les propriétés de l'objet de traitement sont :
C'est encore plus simple, base === owerObject
4. Obtenez la vraie valeur du type de référence
Comme nous l'avons dit au début, un type référence n'est qu'une référence, mais il ne stocke pas la valeur réelle. Lorsque la valeur réelle est nécessaire, elle peut être obtenue grâce à une série d’algorithmes internes. Nous pouvons décrire cet algorithme avec un simple pseudocode :
Copiez le code comme suit :
fonction GetValue (valeur) {
if (Type(valeur) != Référence) {
valeur de retour ;
}
var base = GetBase(valeur);
si (base === null) {
lancer une nouvelle ReferenceError ;
}
return base.[[Get]](GetPropertyName(value));
}
La méthode interne [[Get]] renvoie la vraie valeur des propriétés de l'objet, y compris l'analyse des propriétés héritées dans la chaîne de prototypes. Ainsi, grâce à GetValue, nous pouvons également obtenir facilement la valeur réelle du type référence. Par exemple:
Copiez le code comme suit :
GetValue(fooRéférence); // 10
GetValue(barReference); // objet fonction "bar"
Alors, quand devons-nous obtenir la valeur réelle du type référence ?
Généralement, lorsqu'un type de référence doit être attribué, participer à une opération ou est appelé, la valeur réelle doit être obtenue via la méthode GetValue. (Remarque : l'objet obtenu via GetValue n'est plus un type référence)
La relation entre les types de référence et ceci
Le type référence est principalement étroitement lié à ce point dans le contexte de la fonction, et il semble assez différent à différents moments, nous avons donc introduit le type référence pour expliquer spécifiquement ses performances dans le contexte de la fonction.
Les règles générales pour déterminer la valeur de this dans le contexte de la fonction sont les suivantes :
Dans le contexte d'une fonction, cela est fourni par l'appelant et est déterminé par la manière dont la fonction est appelée. Si le côté gauche du support appelant () est une valeur de type référence, celle-ci sera définie sur l'objet de base de la valeur de type référence. Dans les autres cas (toute autre propriété différente du type référence), cette valeur sera nulle. . Cependant, il n'existe pas de situation réelle dans laquelle la valeur de this est nulle, car lorsque la valeur de this est nulle, sa valeur sera implicitement convertie en objet global. Remarque : Dans la cinquième édition d'ECMAScript, la conversion en variables globales n'est plus forcée, mais est affectée à undefined.
Ci-dessous, nous discuterons de trois situations basées sur la différence sur le côté gauche de la tranche d'appel :
(1) Le côté gauche du support appelant est la valeur du type de référence
Cela ne nécessite pas trop d'analyse. L'objet de base est la valeur de ceci. S'il est déclaré sous une variable globale, il pointe vers l'objet global.
Copiez le code comme suit :
var monObjet = {
foo : fonction(){
console.log(this);
}
}
myObject.foo(); //Il ne fait aucun doute que la base de foo est myObject, donc ceci dans la méthode foo pointe vers myObject.
(2) Le côté gauche du support appelant est une valeur de type référence, mais cette valeur est nulle
Copiez le code comme suit :
fonction maFonction() {
var foo = fonction(){
console.log(this);
}
foo(); //AO.foo() => null.foo()
}
maFonction(); //Sortie : Fenêtre {haut : Fenêtre, fenêtre : Fenêtre...}
Lorsqu'une fonction interne est appelée, la base de la fonction interne doit être l'objet actif (OA) dans le contexte d'exécution actuel. Cependant, dans JavaScript, lorsque OA est utilisé comme base, il n'est certainement pas traité comme null. permettez que cela soit null , toutes les bases sont définies sur l'objet global (c'est la source de l'erreur de conception dans le modèle d'appel de cette fonction précédent). Donc dans ce cas, cela pointe vers l'objet global.
(3) Appelez la valeur sur le côté gauche du support qui n'est pas un type de référence
Copiez le code comme suit :
//Exemple simple
(fonction () {
console.log(this); // null => global
})();
//Un exemple plus complexe
var foo = {
barre : fonction () {
console.log(this);
}
} ;
foo.bar(); // Référence, OK => foo
(foo.bar)(); // Référence, OK => foo
(foo.bar = foo.bar)(); // global
(false || foo.bar)(); // global
(foo.bar, foo.bar)(); // global
Lorsque le côté gauche du crochet appelant n'est pas un type référence mais un autre type, il est automatiquement défini sur null et le résultat est l'objet global.
Dans le premier exemple, la fonction immédiate a une expression à gauche de la parenthèse d’appel de fonction, et non une référence.
Le deuxième exemple est beaucoup plus compliqué, analysons-le un par un :
foo.bar(), cela ne fait aucun doute, base est foo, et cela pointe vers foo.
(foo.bar)(), une parenthèse est utilisée ici, qui agit comme un symbole de regroupement, c'est-à-dire qu'elle ne force pas le type référence à exécuter la méthode GetValue et le résultat de l'exécution est exactement le même que ci-dessus.
Les trois suivantes, entre parenthèses, sont des opérations d'affectation, ou des opérations et des opérations sur virgule. Elles forcent toutes le type référence à exécuter la méthode GetValue, renvoyant ainsi un objet fonction. De cette façon, le côté gauche des parenthèses d’appel de fonction n’est plus un type référence, donc cela pointe vers l’objet global.
Résumer
Concernant les types de référence, en fait, je n'en sais pas grand-chose. Je viens de voir le chapitre à ce sujet dans le blog d'Oncle Tom. Afin d'expliquer le principe de valeur de ceci dans le mode d'appel de fonction, j'ai fait une analyse spéciale. incroyable. J'ai toujours pensé qu'il devrait y avoir une certaine relation entre les types de référence et la référence par valeur. De manière inattendue, il n'est utilisé en bolg que pour aider à comprendre cela. Quant à savoir s'il y avait une relation entre les deux auparavant, et s'il y avait une relation, de quel type de relation il s'agissait, je dois encore continuer à étudier et à rechercher.
J'espère que vous pourrez communiquer davantage. Je voudrais remercier Oncle Tom pour cela.