Tout d'abord, rappelez-vous que JavaScript est principalement un langage prototypique plutôt qu'un langue de classe 1 . Foo
n'est pas une classe, c'est une fonction, qui est un objet. Vous pouvez instancier un objet de cette fonction en utilisant le new
qui vous permettra de créer quelque chose de similaire à une classe dans un langage OOP standard.
Je suggère d'ignorer __proto__
la plupart du temps parce qu'il est mal supporté par les différents navigateurs. prototype
travaux.
Si vous avez une instance d'un objet créé à partir d'une fonction 2 et que vous accédez à l'un de ses membres (méthodes, attributs, propriétés, constantes, etc.) de quelque manière que ce soit, l'accès s'effectuera dans la hiérarchie des prototypes jusqu'à ce qu'il (a) trouve le membre, ou (b) ne trouve pas d'autre prototype.
La hiérarchie commence sur l'objet qui a été appelé, puis recherche son objet prototype. Si l'objet prototype a un prototype, elle répète, si aucun prototype n'existe, undefined
est renvoyé.
Par exemple :
foo = {bar: 'baz'};
console.log(foo.bar); // logs "baz"
foo = {};
console.log(foo.bar); // logs undefined
function Foo(){}
Foo.prototype = {bar: 'baz'};
f = new Foo();
console.log(f.bar);
// logs "baz" because the object f doesn't have an attribute "bar"
// so it checks the prototype
f.bar = 'buzz';
console.log( f.bar ); // logs "buzz" because f has an attribute "bar" set
Il me semble que vous avez déjà compris au moins en partie ces parties "de base", mais je dois les rendre explicites, juste pour être sûr.
En JavaScript, tout est un objet 3 .
tout est un objet.
function Foo(){}
ne se contente pas de définir une nouvelle fonction, elle définit un nouvel objet fonction auquel on peut accéder à l'aide de la fonction Foo
.
C'est pourquoi vous pouvez accéder Foo
avec le prototype de Foo.prototype
.
Ce que vous pouvez également faire est de définir plus de fonctions sur Foo
:
Foo.talk = function () {
alert('hello world!');
};
Cette nouvelle fonction est accessible en utilisant :
Foo.talk();
J'espère que vous remarquez maintenant une similitude entre les fonctions sur un objet fonction et une méthode statique.
Pensez à f = new Foo();
comme la création d'une instance de classe, Foo.prototype.bar = function(){...}
comme la définition d'une méthode partagée pour la classe, et Foo.baz = function(){...}
comme la définition d'une méthode statique publique pour la classe.
ECMAScript 2015 a introduit une variété de sucre syntaxique pour ces types de déclarations afin de les rendre plus simples à mettre en œuvre tout en étant plus faciles à lire. L'exemple précédent peut donc être écrit comme suit :
class Foo {
bar() {...}
static baz() {...}
}
qui permet bar
pour être appelé comme :
const f = new Foo()
f.bar()
et baz
pour être appelé comme :
Foo.baz()
1 : <a href="http://es5.github.io/#x7.6.1.2" rel="noreferrer"><code>class</code> était un "futur mot réservé" dans la spécification ECMAScript 5. </a>mais ES6 introduit la possibilité de définir des classes à l'aide de l'attribut <code>class</code> mot-clé.
2 : essentiellement une instance de classe créée par un constructeur, mais il existe de nombreuses différences nuancées que je ne veux pas vous induire en erreur.
3 : <a href="http://es5.github.io/#x4.3.2" rel="noreferrer">valeurs primitives </a>-qui comprennent <code>undefined</code> , <code>null</code> Les booléens, les nombres et les chaînes de caractères ne sont pas techniquement des objets car ils sont des implémentations de langage de bas niveau. Les booléens, les nombres et les chaînes de caractères interagissent toujours avec la chaîne de prototypes comme s'ils étaient des objets, donc pour les besoins de cette réponse, il est plus facile de les considérer comme des "objets" même s'ils ne le sont pas tout à fait.
14 votes
Foo.talk = function ...
1 votes
@downvoterstepintothelight Le
Foo.walk = function() {}
n'aura pas d'effet sur ses instances, puisqu'il ne se trouve pas dans la chaîne des prototypes. Existe-t-il une méthode inter-navigateur permettant de rendre la fonction[[prototype]]
point à sonprototype
?3 votes
Probablement que je n'ai aucune idée de ce que tu veux, parce que les méthodes de la classe n'affectent pas les instances par définition.
0 votes
@downvoterstepintothelight J'en doute, méthode Dans un langage comme python, une instance est capable d'appeler la méthode de sa classe, la différence est la suivante
this
pointeur.