Constructeurs dans les objets JavaScript

Réponses:

408

Utilisation de prototypes:

function Box(color) // Constructor
{
    this.color = color;
}

Box.prototype.getColor = function()
{
    return this.color;
};

Masquer la "couleur" (ressemble un peu à une variable de membre privé):

function Box(col)
{
   var color = col;

   this.getColor = function()
   {
       return color;
   };
}

Usage:

var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue

var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green
pseudo
la source
3
@BorisB, oui vous le faites - cela définit la couleur et getColor sur l'objet Box, sinon vous affectez des variables dans la portée habituelle.
Nick
4
@Jeach oui. J'ai fourni un extrait alternatif qui se cache color. Je dirais que ce que vous utilisez est en grande partie dû à vos préférences personnelles (protection contre simplicité)
Nick
6
@CamiloMartin Bien que cela ne soit pas toujours nécessaire, rendre une variable "privée" (ou dans ce cas, innommable) peut être un moyen utile d'éviter que le code externe ne dépende des détails d'implémentation de votre classe. Même juste l'indication des éléments de la classe qui sont publics / privés peut être utile aux utilisateurs externes.
Nick
49
varfait une variable privée. thisrend une variable publique
EhevuTov
3
@AlanKis (au moins dans certains moteurs Javascript), la trace de la pile ne sera même pas mentionnée Foodans le cas de la fonction anonyme , tandis que dans ce dernier cas, elle saura qu'elle Fooest appelée. Très utile pour le débogage.
Joachim Isaksson
248

Voici un modèle que j'utilise parfois pour un comportement similaire à la POO en JavaScript. Comme vous pouvez le voir, vous pouvez simuler des membres privés (statiques et d'instance) à l'aide de fermetures. Ce new MyClass()qui retournera est un objet avec seulement les propriétés assignées à l' thisobjet et dans l' prototypeobjet de la "classe".

var MyClass = (function () {
    // private static
    var nextId = 1;

    // constructor
    var cls = function () {
        // private
        var id = nextId++;
        var name = 'Unknown';

        // public (this instance only)
        this.get_id = function () { return id; };

        this.get_name = function () { return name; };
        this.set_name = function (value) {
            if (typeof value != 'string')
                throw 'Name must be a string';
            if (value.length < 2 || value.length > 20)
                throw 'Name must be 2-20 characters long.';
            name = value;
        };
    };

    // public static
    cls.get_nextId = function () {
        return nextId;
    };

    // public (shared across instances)
    cls.prototype = {
        announce: function () {
            alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
                  'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
        }
    };

    return cls;
})();

On m'a posé des questions sur l'héritage en utilisant ce modèle, alors voici:

// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
    // We use an intermediary empty constructor to create an
    // inheritance chain, because using the super class' constructor
    // might have side effects.
    var construct = function () {};
    construct.prototype = superCls.prototype;
    cls.prototype = new construct;
    cls.prototype.constructor = cls;
    cls.super = superCls;
}

var MyChildClass = (function () {
    // constructor
    var cls = function (surName) {
        // Call super constructor on this instance (any arguments
        // to the constructor would go after "this" in call(…)).
        this.constructor.super.call(this);

        // Shadowing instance properties is a little bit less
        // intuitive, but can be done:
        var getName = this.get_name;

        // public (this instance only)
        this.get_name = function () {
            return getName.call(this) + ' ' + surName;
        };
    };
    inherit(cls, MyClass); // <-- important!

    return cls;
})();

Et un exemple pour tout utiliser:

var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"

var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"

alert(john instanceof MyClass); // true

Comme vous pouvez le voir, les classes interagissent correctement entre elles (elles partagent l'identifiant statique de MyClass, la announceméthode utilise la bonne get_nameméthode, etc.)

Une chose à noter est la nécessité de masquer les propriétés d'instance. Vous pouvez réellement faire passer la inheritfonction par toutes les propriétés d'instance (en utilisant hasOwnProperty) qui sont des fonctions, et ajouter automatiquement une super_<method name>propriété. Cela vous permettrait d'appeler this.super_get_name()au lieu de le stocker dans une valeur temporaire et de l'appeler lié à l'aide call.

Pour les méthodes sur le prototype, vous n'avez pas à vous soucier de ce qui précède cependant, si vous voulez accéder aux méthodes de prototype de la super classe, vous pouvez simplement appeler this.constructor.super.prototype.methodName. Si vous voulez le rendre moins verbeux, vous pouvez bien sûr ajouter des propriétés de commodité. :)

Blixt
la source
7
Juste une note à propos de la cls.prototypepartie: "partagé entre les instances" sert uniquement à lire la valeur (appel announce). Si vous définissez myClassInstance.announceune autre valeur, il crée une nouvelle propriété dans myClassInstance, il ne s'applique donc qu'à cet objet, pas aux autres instances de la classe. L'affectation à MyClass.prototype.announceaffectera cependant toutes les instances.
Matthew Crumley
1
Pas de problème, heureux de vous aider! :)
Blixt
2
Je vous remercie! Très aimé! Pourriez-vous montrer un exemple d'héritage de classe dans cette approche.
Dmitrij Golubev
2
@DmitrijGolubev, Brad Dwyer et Nathan C. Tresch: J'ai ajouté l'héritage, mais cela devient assez compliqué, donc je vous conseillerais généralement d'aller avec une solution plus simple, à moins que vous ayez besoin d'un tel héritage hardcore en JavaScript (qui est vraiment juste un langage prototypique).
Blixt
1
@guiomie C'est une méthode "publique statique" donc vous l'appelleriez sur la fonction constructeur (la "classe"), pas l'instance:MyClass.get_nextId()
Blixt
166

Il me semble que la plupart d'entre vous donnent des exemples de getters et setters qui ne sont pas des constructeurs, à savoir http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming) .

lunched-dan était plus proche mais l'exemple ne fonctionnait pas dans jsFiddle.

Cet exemple crée une fonction constructeur privée qui ne s'exécute que lors de la création de l'objet.

var color = 'black';

function Box()
{
   // private property
   var color = '';

   // private constructor 
   var __construct = function() {
       alert("Object Created.");
       color = 'green';
   }()

   // getter
   this.getColor = function() {
       return color;
   }

   // setter
   this.setColor = function(data) {
       color = data;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange');

alert(b.getColor()); // should be orange

alert(color); // should be black

Si vous souhaitez attribuer des propriétés publiques, le constructeur peut être défini comme tel:

var color = 'black';

function Box()
{
   // public property
   this.color = '';

   // private constructor 
   var __construct = function(that) {
       alert("Object Created.");
       that.color = 'green';
   }(this)

   // getter
   this.getColor = function() {
       return this.color;
   }

   // setter
   this.setColor = function(color) {
       this.color = color;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange'); 

alert(b.getColor()); // should be orange

alert(color); // should be black
Jon
la source
45
Comment n'est-ce pas la réponse n ° 1? Seul Jon a créé un constructeur avec des paramètres.
Rap
1
Existe-t-il un moyen d'obtenir un exemple d'héritage en utilisant ce paradigme pour les constructeurs?
Nathan C. Tresch
1
L'exemple de constructeur de @Rap Jon n'a pas de paramètres car c'est une Box()fonction :). Mais cet exemple ainsi que les exemples des autres réponses peuvent être facilement étendus pour accepter les paramètres.
Alexander Stepaniuk
2
@AndersonGreen, vous pouvez ajouter un paramètre à Box, puis le transmettre au constructeur privé en tant que paramètre de fonction.
Gautham C.
1
Pas besoin de "constructeurs privés". Faites simplement votre construction dans la Boxfonction et vous êtes prêt à partir (c'est toujours "privé"). "Privé" en Javascript signifie simplement accessible via une portée lexicale; pas besoin d'affecter aux membres. De plus: ce code est erroné. Il crée une __constructvariable globale , ce qui est assez mauvais. vardevrait être utilisé pour restreindre la portée de __construct.
mattbasta
23

Quel est donc l'intérêt de la propriété "constructeur"? Vous ne savez pas où cela pourrait être utile, des idées?

Le but de la propriété constructeur est de fournir un moyen de prétendre que JavaScript a des classes. L'une des choses que vous ne pouvez pas faire utilement est de modifier le constructeur d'un objet après sa création. C'est compliqué.

J'ai écrit un article assez complet à ce sujet il y a quelques années: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

Joost Diepenmaat
la source
Il s'agit d'utiliser le "nouveau" mot-clé. "d = new Drofto ()" crée un objet vide et exécute la fonction Drofto avec ledit nouvel objet délimité comme "this". La fonction Drofto est libre de renvoyer n'importe quoi, mais il est habituel de renvoyer quelque chose pour être considéré comme un membre de la classe Drofto.
Juan Lanus
16

Exemple ici: http://jsfiddle.net/FZ5nC/

Essayez ce modèle:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
  v1: null
 ,v2: null
 ,f1: function Name_Space_ClassName_f1(){}
}

//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;

//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>

Vous devez ajuster votre espace de noms si vous définissez une classe statique:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>

Exemple de classe:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
    this.Width = width;
    this.Height = height;
    this.Color = color;
}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
  Width: null
 ,Height: null
 ,Color: null
 ,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
    var canvas = document.getElementById(canvasId);
    var context = canvas.getContext("2d");
    context.fillStyle = this.Color;
    context.fillRect(x, y, this.Width, this.Height);
 }
}

//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;

//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
    return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
    return new Shape.Rectangle(50,25,'#ff0000');
}
</script>

Exemple d'instanciation:

<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");

var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);

var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);

Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>

Les fonctions d'avis sont définies comme AB = fonction A_B (). C'est pour rendre votre script plus facile à déboguer. Ouvrez le panneau Inspect Element de Chrome, exécutez ce script et développez la trace de débogage:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};

//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
    A.Func.That.Does.Not.Exist();
}

Fail.Test();
</script>
mousser
la source
Exemple ajouté. Ajout d'informations sur l'amélioration de la sortie de débogage.
bitlather
1
Probablement parce qu'il ajoute un niveau de complexité inutile au problème. Il est difficile de trouver la réponse dans votre message en raison de l'espacement des noms pédant et de la déclaration de classe statique. Ne vous méprenez pas, c'est une bonne information mais c'est certainement plus déroutant qu'utile si vous essayez de mettre un pied dans la porte pour comprendre. Je suis à moitié compétent en JS et je comprends à peine ce que vous faites ici, ou pourquoi c'est pertinent pour "Comment puis-je construire?"
Bmo
1
Merci pour la perspicacité, Bmo. C'était un long article, mais c'est parce que je ne comprends pas l'utilisation d'un constructeur s'il n'est pas lié à un objet bien défini et à une implémentation de classe statique. Lorsque vous apprenez C ++ ou Java, vous devez apprendre à implémenter des classes et à implémenter des constructeurs. Le développement Web est devenu beaucoup plus agréable depuis que je suis tombé sur cette méthode d'écriture javascript, et je voulais juste partager. J'ai déplacé le violon vers le haut pour qu'il soit plus facile à trouver. J'espère que cela clarifiera toute confusion.
bitlather
1
@Bmo Êtes-vous sérieux que les deux lignes concernant l'espace de noms rendent difficile de trouver le constructeur exactement ci-dessous, en particulier compte tenu du commentaire Constructeur - DOIT ÊTRE EN HAUT DE FICHIER? Fournir un exemple d'espace de noms est le bienvenu, la communauté de développeurs javascript ignore aveuglément les espaces de noms, ce qui provoque des erreurs difficiles à trouver lorsque les noms s'affrontent. Il est triste de voir que les développeurs js pensent que s'ils copient un morceau de texte d'un post sur Internet et font quelque chose de similaire à ce dont ils ont besoin, leur travail est terminé.
user3285954
1
Le problème majeur avec js et le développement web en général est que la plupart des développeurs ignorent toutes les pratiques que l'industrie a créées depuis plus de 50 ans et pensent que s'ils peuvent faire un appel ajax, ils sont le roi. C'est tellement triste de voir qu'il a fallu tant d'années pour commencer à utiliser des modèles et des pratiques bien connus en javascript.
user3285954
10

Ceci est un constructeur:

function MyClass() {}

Quand tu fais

var myObj = new MyClass();

MyClass est exécuté et un nouvel objet est renvoyé de cette classe.

Satish N Ramteare
la source
1
Pour clarifier, ce que cela signifie est au sommet de votre classe, vous pouvez dire alert(valuePassedInAsArgument);et cela s'exécutera une fois pour chaque instanciation, donc toute la classe est le constructeur lui-même.
Martin Lyne
new object is returned of that class- n'est-ce pas plutôt comme si un nouvel objet est renvoyé de cette fonction?
Don Cheadle
dans les fonctions javascript sont des objets
Leo
8

J'ai trouvé ce tutoriel très utile. Cette approche est utilisée par la plupart des plug-ins jQuery.

http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK

var Class = function(methods) {   
    var klass = function() {    
        this.initialize.apply(this, arguments);          
    };  

    for (var property in methods) { 
       klass.prototype[property] = methods[property];
    }

    if (!klass.prototype.initialize) klass.prototype.initialize = function(){};      

    return klass;    
};

Maintenant ,

var Person = Class({ 
    initialize: function(name, age) {
        this.name = name;
        this.age  = age;
    },
    toString: function() {
        return "My name is "+this.name+" and I am "+this.age+" years old.";
    }
}); 

var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"
anasanjaria
la source
10
Je grince des dents chaque fois que je vois des gens utiliserklass
Madbreaks
8

Ce schéma m'a bien servi. Avec ce modèle, vous créez des classes dans des fichiers séparés, les chargez dans votre application globale "au besoin".

// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};

// "Package" 
// Similar to how you would establish a package in other languages
(function() {

// "Class"
var MyClass = function(params) {
    this.initialize(params);
}

    // "Private Static" vars 
    //    - Only accessible to functions in this class.
    //    - Doesn't get wiped out when we create a new instance.
    var countInstances = 0;
    var allInstances = [];

    // "Private Static" functions 
    //    - Same as above, but it's a function accessible 
    //      only to other functions in this class.
    function doSomething(){
    }

    // "Public Static" vars
    //    - Everyone has access.
    //    - Doesn't get wiped out when we create a new instance.
    MyClass.counter = 0;

    // "Public Static" functions
    //    - Same as above, but anyone can call this "static method".
    //    - Kinda like a singleton class situation.
    MyClass.foobar = function(){
    }

    // Public properties and methods are built into the "prototype"
    //    - This is how each instance can become unique unto itself.
    //    - Establishing "p" as "local" (Static Private) variable 
    //      simply so we don't have to keep typing "MyClass.prototype" 
    //      for each property and function.
var p = MyClass.prototype;

    // "Public" vars
    p.id = null;
    p.firstname = null;
    p.lastname = null;

    // "Private" vars
    //    - Only used by "this" instance.
    //    - There isn't "true" privacy for each 
    //      instance so we have to fake it. 
    //    - By tradition, we indicate "privacy"  
    //      by prefixing it with an underscore. 
    //    - So technically, anyone can access, but we simply 
    //      don't tell anyone about it (e.g. in your API)
    //      so no one knows about it :)
    p._foo = null;

    p.initialize = function(params){
        this.id = MyClass.counter++;
        this.firstname = params.firstname;
        this.lastname = params.lastname;
        MyClass.counter++;
        countInstances++;
        allInstances.push(this);
    }

    p.doAlert = function(theMessage){
        alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ".  Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
    }


// Assign class to app
myApp.MyClass = MyClass;

// Close the "Package"
}());

// Usage example:
var bob = new myApp.MyClass({   firstname   :   "bob",
                                lastname    :   "er"
                            });

bob.doAlert("hello there");
bob
la source
Ce sont des variables d'instance mais elles ont une accessibilité "publique", pas "privée" comme en C ++ ou Java.
Potatoswatter
Comment procéderiez-vous pour créer une variable privée (au sens classique) qui est relative à l'instance, mais pas commune à toutes les instances?
bob
Voir le site de Douglas Crockford , il est l'un des concepteurs linguistiques et une autorité de premier plan. Je ne suis pas toujours ses modèles, mais en général une variable privée est un local vardans le constructeur (ou argument de fonction, ou dans une fonction de type constructeur).
Potatoswatter
Merci pour l'astuce ... la page suivante explique ce que je cherchais: javascript.crockford.com/private.html
bob
Oh, désolé de ne pas avoir testé le lien: P
Potatoswatter
8

Oui, vous pouvez définir un constructeur dans une déclaration de classe comme ceci:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
Bruno
la source
pour vaersion IE> 12
zloctb
1
Ceci est la seule réponse réelle à la question. : /
MarcD
6

Je suppose que je posterai ce que je fais avec la fermeture javascript car personne n'utilise encore la fermeture.

var user = function(id) {
  // private properties & methods goes here.
  var someValue;
  function doSomething(data) {
    someValue = data;
  };

  // constructor goes here.
  if (!id) return null;

  // public properties & methods goes here.
  return {
    id: id,
    method: function(params) {
      doSomething(params);
    }
  };
};

Les commentaires et suggestions sur cette solution sont les bienvenus. :)

Hendra Uzia
la source
1
Quelques commentaires: 1) déclaration si (! Id) n'est pas sûr, des valeurs comme 0 ou false le feront évaluer vrai et retourner nul. Je suppose que vous voulez vérifier non défini ou nul, auquel cas === null et === non défini serait mieux. 2) Cela ressemble plus au modèle de module ( adéquatement good.com/2010/3/JavaScript-Module-Pattern-In-Depth) qu'à un constructeur, la différence étant qu'un module renvoie un objet à partir de la fonction tandis qu'un constructeur crée un objet lorsque jumelé avec le nouveau mot clé, et dans ce cas, vous définiriez des valeurs sur «ceci» au lieu d'un objet.
Rich
4

En utilisant l'exemple de Nick ci-dessus, vous pouvez créer un constructeur pour les objets sans paramètres en utilisant une instruction return comme dernière instruction dans votre définition d'objet. Renvoyez votre fonction constructeur comme ci-dessous et elle exécutera le code dans __construct chaque fois que vous créez l'objet:

function Box()
{
   var __construct = function() {
       alert("Object Created.");
       this.color = 'green';
   }

  this.color = '';

   this.getColor = function() {
       return this.color;
   }

   __construct();
}

var b = new Box();
Dan Power
la source
1
Vous ne renvoyez pas la fonction constructeur, vous l'appelez simplement.
David Conrad
Si vous essayez d'utiliser this.getColor();sur la ligne ci-dessus, alert("Object Created.");rien ne sera alerté. Il y aura une erreur comme "getColor n'est pas défini". Si vous voulez que la construction puisse appeler d'autres méthodes dans l'objet, elle doit être définie après toutes les autres méthodes. Donc, au lieu d'appeler __construct();sur la dernière ligne, définissez simplement la construction là-bas et mettez-la ()après pour la forcer à s'exécuter automatiquement.
thinsoldier
Correction. L'ajout ()à la fin de la définition de __construct a toujours entraîné l'erreur. J'ai dû appeler __construct();sur sa propre ligne comme dans le code d'origine pour éviter l'erreur.
thinsoldier
4

C'est peut-être devenu un peu plus simple, mais voici ce que j'ai trouvé maintenant en 2017:

class obj {
  constructor(in_shape, in_color){
    this.shape = in_shape;
    this.color = in_color;
  }

  getInfo(){
    return this.shape + ' and ' + this.color;
  }
  setShape(in_shape){
    this.shape = in_shape;
  }
  setColor(in_color){
    this.color = in_color;
  }
}

En utilisant la classe ci-dessus, j'ai les éléments suivants:

var newobj = new obj('square', 'blue');

//Here, we expect to see 'square and blue'
console.log(newobj.getInfo()); 

newobj.setColor('white');
newobj.setShape('sphere');

//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());

Comme vous pouvez le voir, le constructeur prend deux paramètres et nous définissons les propriétés de l'objet. Nous modifions également la couleur et la forme de l'objet en utilisant les setterfonctions, et prouvons que son changement est resté lors de l'appel getInfo()après ces changements.

Un peu tard, mais j'espère que cela vous aidera. J'ai testé cela avec un mochatest unitaire, et cela fonctionne bien.

Chim Chimz
la source
3

Ils le font si vous utilisez Typescript - open source de MicroSoft :-)

class BankAccount {
 balance: number;
 constructor(initially: number) {
 this.balance = initially;
 }
 deposit(credit: number) {
 this.balance += credit;
 return this.balance;
 }
}

Typescript vous permet de «fausses» constructions OO qui sont compilées en constructions javascript. Si vous démarrez un grand projet, cela peut vous faire gagner beaucoup de temps et il vient d'atteindre la version 1.0.

http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf

Le code ci-dessus est «compilé» pour:

var BankAccount = (function () {
    function BankAccount(initially) {
        this.balance = initially;
    }
    BankAccount.prototype.deposit = function (credit) {
        this.balance += credit;
        return this.balance;
    };
    return BankAccount;
})();
Simon_Weaver
la source
Je travaille sur un grand projet et j'essaie de convaincre les gens que TypeScript nous donnera une séance photo en cours. Nous verrons comment cela se passe.
wootscootinboogie
@wootscootinboogie En une journée (se terminant à 5h30 en ce moment), je suis assez loin et assez à l'aise avec ça. Je recommande fortement de lire la spécification et même si vous pouvez ignorer la moitié des vraies choses sérieuses, vous vous faites une faveur en les lisant au moins une fois. les vidéos de ce type sont excellentes youtube.com/user/basaratali/videos . bonne chance)
Simon_Weaver
1

En JavaScript, le type d'invocation définit le comportement de la fonction:

  • Invocation directe func()
  • Appel de méthode sur un objet obj.func()
  • Invocation de constructeurnew func()
  • Invocation indirecte func.call()oufunc.apply()

La fonction est invoquée en tant que constructeur lors de l'appel à l'aide de l' newopérateur:

function Cat(name) {
   this.name = name;
}
Cat.prototype.getName = function() {
   return this.name;
}

var myCat = new Cat('Sweet'); // Cat function invoked as a constructor

Toute instance ou objet prototype en JavaScript possède une propriété constructor, qui fait référence à la fonction constructeur.

Cat.prototype.constructor === Cat // => true
myCat.constructor         === Cat // => true

Consultez cet article sur la propriété constructeur.

Dmitri Pavlutin
la source
0

Tout en utilisant l'excellent modèle de Blixt d'en haut, j'ai découvert qu'il ne fonctionne pas bien avec l'héritage à plusieurs niveaux (MyGrandChildClass étendant MyChildClass étendant MyClass) - il passe en boucle en appelant le constructeur du premier parent encore et encore. Voici donc une solution de contournement simple - si vous avez besoin d'un héritage à plusieurs niveaux, au lieu d'utiliser l' this.constructor.super.call(this, surName);utilisation chainSuper(this).call(this, surName);avec la fonction de chaîne définie comme ceci:

function chainSuper(cls) {
  if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
  var depth = cls.__depth;
  var sup = cls.constructor.super;
  while (depth > 1) {
    if (sup.super != undefined) sup = sup.super;
    depth--;
  }
  return sup;
}
Jan
la source
0

http://www.jsoops.net/ est assez bon pour oop dans Js. Si fournir une variable et une fonction privées, protégées et publiques, ainsi qu'une fonction d'héritage. Exemple de code:

var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public

    pri.className = "I am A ";

    this.init = function (var1)// constructor
    {
        pri.className += var1;
    }

    pub.getData = function ()
    {
        return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
        + ", ID=" + pro.getClassId() + ")";
    }

    pri.getClassName = function () { return pri.className; }
    pro.getClassName = function () { return pri.className; }
    pro.getClassId = function () { return 1; }
});

var newA = new ClassA("Class");

//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)

//***You can not access constructor, private and protected function
console.log(typeof (newA.init));            // undefined
console.log(typeof (newA.className));       // undefined
console.log(typeof (newA.pro));             // undefined
console.log(typeof (newA.getClassName));    // undefined
user1624059
la source
0

juste pour offrir une certaine variété. ds.oop est un bon moyen de déclarer des classes avec des constructeurs en javascript. Il prend en charge tous les types d'héritage possibles (y compris 1 type que même c # ne prend pas en charge) ainsi que les interfaces, ce qui est bien.

var Color = ds.make.class({
    type: 'Color',
    constructor: function (r,g,b) { 
        this.r = r;                     /* now r,g, and b are available to   */
        this.g = g;                     /* other methods in the Color class  */
        this.b = b;                     
    }
});
var red = new Color(255,0,0);   // using the new keyword to instantiate the class
dss
la source
0

Ici, nous devons noter un point dans le script java, c'est un langage sans classe cependant, nous pouvons y parvenir en utilisant des fonctions dans le script java. La façon la plus courante d'y parvenir consiste à créer une fonction dans un script java et à utiliser un nouveau mot-clé pour créer un objet et à utiliser ce mot - clé pour définir la propriété et les méthodes. Ci-dessous est l'exemple.

// Function constructor

   var calculator=function(num1 ,num2){
   this.name="This is function constructor";
   this.mulFunc=function(){
      return num1*num2
   };

};

var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call

//Constructors With Prototypes

var calculator=function(){
   this.name="Constructors With Prototypes";
};

calculator.prototype.mulFunc=function(num1 ,num2){
 return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call
Sheo Dayal Singh
la source
-2

Dans la plupart des cas, vous devez déclarer en quelque sorte la propriété dont vous avez besoin avant de pouvoir appeler une méthode qui transmet ces informations. Si vous n'avez pas à définir initialement une propriété, vous pouvez simplement appeler une méthode dans l'objet comme ceci. Ce n'est probablement pas la plus jolie façon de le faire, mais cela fonctionne toujours.

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
Conteneur codé
la source