272 votes

Classe et méthode statique en JavaScript

Je sais que ça va marcher :

function Foo() {};
Foo.prototype.talk = function () {
    alert('hello~\n');
};

var a = new Foo;
a.talk(); // 'hello~\n'

Mais si je veux appeler

Foo.talk() // this will not work
Foo.prototype.talk() // this works correctly

Je trouve des méthodes pour faire Foo.talk travail,

  1. Foo.__proto__ = Foo.prototype
  2. Foo.talk = Foo.prototype.talk

Y a-t-il d'autres façons de procéder ? Je ne sais pas si c'est bien de le faire. Utilisez-vous des méthodes de classe ou des méthodes statiques dans votre code JavaScript ?

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 à son prototype ?

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.

12voto

A-Sharabiani Points 5287

J'utilise des espaces de noms :

var Foo = {
     element: document.getElementById("id-here"),

     Talk: function(message) {
            alert("talking..." + message);
     },

     ChangeElement: function() {
            this.element.style.color = "red";
     }
};

Et de l'utiliser :

Foo.Talk("Testing");

Ou

Foo.ChangeElement();

7voto

ES6 supporte maintenant class & static mots-clés comme un charme :

class Foo {
    constructor() {}

    talk() {
        console.log("i am not static");
    }

    static saying() {
        console.log(this.speech);
    }

    static get speech() {
        return "i am static method";
    }

}

4voto

Combine Points 820

Si vous devez écrire des méthodes statiques dans ES5, j'ai trouvé un excellent tutoriel pour cela :

//Constructor
var Person = function (name, age){
//private properties
var priv = {};

//Public properties
this.name = name;
this.age = age;

//Public methods
this.sayHi = function(){
    alert('hello');
}
}

// A static method; this method only 
// exists on the class and doesn't exist  
// on child objects
Person.sayName = function() {
   alert("I am a Person object ;)");  
};

voir @ https://abdulapopoola.com/2013/03/30/static-and-instance-methods-in-javascript/

4voto

ngakak Points 66

Juste des notes supplémentaires. Avec la classe ES6, lorsque nous créons des méthodes statiques, le moteur Javacsript définit l'attribut descriptor d'une manière un peu différente de la méthode "statique" traditionnelle.

function Car() {

}

Car.brand = function() {
  console.log('Honda');
}

console.log(
  Object.getOwnPropertyDescriptors(Car)
);

il fixe l'attribut interne (propriété du descripteur) pour brand() à

..
brand: [object Object] {
    configurable: true,
    enumerable: true,
    value: ..
    writable: true

}
..

par rapport à

class Car2 {
   static brand() {
     console.log('Honda');
   }
}

console.log(
  Object.getOwnPropertyDescriptors(Car2)
);

qui définit l'attribut interne pour brand() à

..
brand: [object Object] {
    configurable: true,
    enumerable: false,
    value:..
    writable: true
  }

..

voir que énumérable est réglé sur faux pour les méthodes statiques dans ES6.

cela signifie que vous ne pouvez pas utiliser la boucle for-in pour vérifier l'objet

for (let prop in Car) {
  console.log(prop); // brand
}

for (let prop in Car2) {
  console.log(prop); // nothing here
}

La méthode statique dans ES6 est traitée comme une propriété privée d'une autre classe (nom, longueur, constructeur) sauf que la méthode statique est toujours accessible en écriture donc le descripteur. accessible en écriture est réglé sur vrai { writable: true } . cela signifie également que nous pouvons l'ignorer.

Car2.brand = function() {
   console.log('Toyota');
};

console.log(
  Car2.brand() // is now changed to toyota
);

2voto

Issac Young Points 56

Quand vous essayez d'appeler Foo.talk le JS essaie de rechercher une fonction talk par le biais de __proto__ et, bien sûr, il est introuvable.

Foo.__proto__ est Function.prototype .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X