Costruttori in oggetti JavaScript


Risposte:


408

Utilizzando prototipi:

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

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

Nascondere "color" (ricorda in qualche modo una variabile membro privata):

function Box(col)
{
   var color = col;

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

Uso:

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

var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green

3
@BorisB, sì, sì: questo definisce color e getColor sull'oggetto Box, altrimenti si stanno assegnando variabili nel solito ambito.
Nick,

4
@Sì, sì. Ho fornito uno snippet alternativo che si nasconde color. Suggerirei che usi in gran parte in base alle preferenze personali (protezione contro semplicità)
Nick,

6
@CamiloMartin Anche se non sempre necessario, rendere una variabile "privata" (o, in questo caso, non modificabile) può essere un modo utile per evitare che il codice esterno diventi dipendente dai dettagli di implementazione della tua classe. Anche solo l'indicazione di quali elementi della classe sono pubblici / privati ​​può essere utile per gli utenti esterni.
Nick,

49
varcrea una variabile privata. thisrende una variabile pubblica
EhevuTov

3
@AlanKis (almeno in alcuni motori Javascript) la traccia dello stack non menzionerà nemmeno nel caso di funzione anonima Foo, mentre in quest'ultimo caso saprà che Fooviene chiamata. Molto utile per il debug.
Joachim Isaksson,

248

Ecco un modello che a volte utilizzo per comportamenti simili a OOP in JavaScript. Come puoi vedere, puoi simulare membri privati ​​(sia statici che di istanza) usando le chiusure. Ciò new MyClass()che restituirà è un oggetto con solo le proprietà assegnate thisall'oggetto e prototypeall'oggetto della "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;
})();

Mi è stato chiesto dell'ereditarietà usando questo modello, quindi ecco qui:

// 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;
})();

E un esempio per usarlo tutto:

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

Come puoi vedere, le classi interagiscono correttamente tra loro (condividono l'id statico MyClass, il announcemetodo utilizza il get_namemetodo corretto , ecc.)

Una cosa da notare è la necessità di ombreggiare le proprietà dell'istanza. Puoi effettivamente far inheritpassare la funzione attraverso tutte le proprietà dell'istanza (usando hasOwnProperty) che sono funzioni e aggiungere automagicamente una super_<method name>proprietà. Questo ti permetterebbe di chiamare this.super_get_name()invece di memorizzarlo in un valore temporaneo e chiamarlo associato usando call.

Per i metodi sul prototipo non devi preoccuparti di quanto sopra, tuttavia, se vuoi accedere ai metodi prototipo della super classe, puoi semplicemente chiamare this.constructor.super.prototype.methodName. Se vuoi renderlo meno dettagliato puoi ovviamente aggiungere proprietà di convenienza. :)


7
Solo una nota sulla cls.prototypeparte: "condivisa su più istanze" serve solo per leggere il valore (chiamata announce). Se si imposta myClassInstance.announcesu un altro valore, crea una nuova proprietà in myClassInstance, quindi si applica solo a quell'oggetto, non ad altre istanze della classe. L'assegnazione a MyClass.prototype.announceinteresserà comunque tutte le istanze.
Matthew Crumley,

1
Nessun problema, felice di essere di aiuto! :)
Blixt,

2
Grazie! Mi è piaciuto molto! Potresti mostrare un esempio di eredità di classe in questo approccio.
Dmitrij Golubev,

2
@DmitrijGolubev, Brad Dwyer e Nathan C. Tresch: ho aggiunto l'ereditarietà, ma sta diventando piuttosto complicato, quindi di solito ti consiglierei di andare con una soluzione più semplice, a meno che tu non abbia bisogno di tale eredità hardcore in JavaScript (che è davvero solo un linguaggio prototipo).
Blixt,

1
@guiomie È un metodo "statico pubblico", quindi lo chiameresti sulla funzione di costruzione (la "classe"), non sull'istanza:MyClass.get_nextId()
Blixt,

166

Mi sembra che molti di voi stiano dando esempi di getter e setter, non un costruttore, ad esempio http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming) .

lunched-dan era più vicino ma l'esempio non funzionava in jsFiddle.

In questo esempio viene creata una funzione di costruzione privata che viene eseguita solo durante la creazione dell'oggetto.

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

Se si desidera assegnare proprietà pubbliche, il costruttore potrebbe essere definito come tale:

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

45
In che modo questa non è la risposta n. 1? Solo Jon ha creato un costruttore con parametri.
Rap

1
Esiste un modo per ottenere un esempio di eredità usando questo paradigma per i costruttori?
Nathan C. Tresch,

1
L'esempio del costruttore di @Rap Jon non ha parametri in quanto è Box()funzione :). Ma questo esempio così come gli esempi nelle altre risposte possono essere facilmente estesi per accettare i parametri.
Alexander Stepaniuk,

2
@AndersonGreen è possibile aggiungere un parametro a Box e quindi passarlo al costruttore privato come parametro di funzione.
Gautham C.,

1
Non sono necessari "costruttori privati". Fai semplicemente la tua costruzione nella Boxfunzione e sei a posto (è ancora "privato"). "Privato" in Javascript significa semplicemente accessibile tramite ambito lessicale; non è necessario assegnare ai membri. Inoltre: questo codice è sbagliato. Crea una __constructvariabile globale , che è piuttosto male. vardovrebbe essere usato per limitare la portata di __construct.
Mattbasta,

23

Allora, qual è il punto della proprietà "costruttore"? Non riesci a capire dove potrebbe essere utile, qualche idea?

Il punto della proprietà del costruttore è fornire un modo per fingere che JavaScript abbia delle classi. Una delle cose che non puoi fare utilmente è cambiare il costruttore di un oggetto dopo che è stato creato. È complicato.

Ne ho scritto un pezzo abbastanza completo alcuni anni fa: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html


Il punto è usare la "nuova" parola chiave. "d = new Drofto ()" crea un oggetto vuoto ed esegue la funzione Drofto con detto nuovo oggetto limitato come "this". La funzione Drofto è libera di restituire qualsiasi cosa, ma è consuetudine restituire qualcosa da considerare come membro della classe Drofto.
Juan Lanus,

16

Esempio qui: http://jsfiddle.net/FZ5nC/

Prova questo modello:

<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>

Devi adattare il tuo spazio dei nomi se stai definendo una classe statica:

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

Classe di esempio:

<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>

Esempio di istanza:

<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>

Le funzioni di avviso sono definite come AB = funzione A_B (). Questo per facilitare il debug del tuo script. Apri il pannello Inspect Element di Chrome, esegui questo script ed espandi il backtrace di debug:

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

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

Fail.Test();
</script>

Esempio aggiunto. Aggiunte anche informazioni sul miglioramento dell'output di debug.
amorevole

1
Probabilmente perché aggiunge un inutile livello di complessità al problema. È difficile trovare la risposta nel tuo post a causa della spaziatura del nome pedante e della dichiarazione di classe statica. Non fraintendetemi, è una buona informazione ma è sicuramente più confuso che utile se state cercando di capire la comprensione. Sono a metà competenza in JS e capisco a malapena quello che stai facendo qui, o perché è rilevante per "Come faccio a costruire?"
Bmo,

1
Grazie per la comprensione, Bmo. Era un post lungo, ma è perché non capisco l'uso di un costruttore se non è legato a un oggetto ben definito e all'implementazione di una classe statica. Quando apprendi C ++ o Java, devi imparare come implementare le classi insieme a come implementare i costruttori. Web dev è diventato molto più divertente da quando mi sono imbattuto in questo metodo di scrittura di JavaScript e volevo solo condividere. Ho spostato il violino verso l'alto, quindi è più facile da trovare. Spero che ciò chiarisca qualsiasi confusione.
Bitlather,

1
@Bmo Sei serio sul fatto che le due righe sullo spazio dei nomi rendono difficile trovare il costruttore esattamente sotto, specialmente dato il commento Costruttore - DEVE ESSERE IN ALTO AL FILE? Fornire un esempio con lo spazio dei nomi è molto gradito, la comunità di sviluppatori javascript ignora ciecamente gli spazi dei nomi causando errori difficili da trovare quando i nomi si scontrano. È triste vedere che gli sviluppatori js pensano che se copiano un pezzo di testo da un post su Internet e fanno qualcosa di simile a ciò di cui hanno bisogno, il loro lavoro è completo.
user3285954

1
Il problema principale con js e lo sviluppo web in generale è che la maggior parte degli sviluppatori ignora tutte le pratiche che l'industria ha creato in oltre 50 anni e pensa che se possono fare una chiamata ajax sono il re. Così triste da vedere che ci sono voluti così tanti anni per iniziare a utilizzare modelli e pratiche ben noti in JavaScript.
user3285954

10

Questo è un costruttore:

function MyClass() {}

Quando lo fai

var myObj = new MyClass();

MyClass viene eseguito e viene restituito un nuovo oggetto di quella classe.


1
Per chiarire, ciò che questo significa è al vertice della tua classe che puoi dire alert(valuePassedInAsArgument);e questo verrà eseguito una volta per ogni istanza, quindi l'intera classe è il costruttore stesso.
Martin Lyne,

new object is returned of that class- non è più come un nuovo oggetto restituito da quella funzione?
Don Cheadle,

in javascript le funzioni sono oggetti
Leo,

8

Ho trovato questo tutorial molto utile. Questo approccio è utilizzato dalla maggior parte dei plug-in 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;    
};

Adesso ,

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]"

10
Mi arrabbio ogni volta che vedo persone che usanoklass
Madbreaks

8

Questo modello mi ha servito bene. Con questo modello, crei le classi in file separati, caricandole nella tua app generale "secondo necessità".

// 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");

Quelle sono variabili di istanza ma hanno accessibilità "pubblica", non "privata" come in C ++ o Java.
Potatoswatter il

Come faresti a creare una variabile privata (nel senso classico) relativa all'istanza, ma non comune a tutte le istanze?
bob

Vedi il sito di Douglas Crockford , è uno dei progettisti del linguaggio e la massima autorità. Non seguo sempre i suoi schemi, ma in generale una variabile privata è un locale varnel costruttore (o argomento di funzione, o in una funzione simile a un costruttore).
Potatoswatter il

Grazie per la punta ... la pagina seguente spiega cosa stavo cercando: javascript.crockford.com/private.html
bob

Oh, scusa per non aver testato il link: P
Potatoswatter


6

Immagino che posterò quello che faccio con la chiusura di JavaScript poiché nessuno sta ancora usando la chiusura.

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);
    }
  };
};

Commenti e suggerimenti per questa soluzione sono i benvenuti. :)


1
Un paio di commenti: 1) se if (! Id) non è sicuro, valori come 0 o false lo faranno valutare true e restituiranno null. Immagino che tu voglia verificare undefined o null nel qual caso === null e === undefined sarebbe meglio. 2) Questo assomiglia più da vicino il modello Module ( adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth ) contro un costruttore, la differenza essendo un modulo restituisce un oggetto dalla funzione mentre un costruttore crea un oggetto quando accoppiato con la nuova parola chiave, e in tal caso dovresti impostare i valori su "this" anziché su un oggetto.
Ricco

4

Usando l'esempio di Nick sopra, puoi creare un costruttore per oggetti senza parametri usando un'istruzione return come ultima istruzione nella definizione dell'oggetto. Restituisce la funzione di costruzione come di seguito e eseguirà il codice in __construct ogni volta che si crea l'oggetto:

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

  this.color = '';

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

   __construct();
}

var b = new Box();

1
Non stai restituendo la funzione di costruzione, la stai solo chiamando.
David Conrad,

Se si tenta di utilizzare this.getColor();sulla riga sopra alert("Object Created.");nulla verrà avvisato. Ci sarà un errore come "getColor non è definito". Se si desidera che il costrutto sia in grado di chiamare altri metodi nell'oggetto, è necessario definirlo dopo tutti gli altri metodi. Quindi, invece di chiamare __construct();l'ultima riga, definisci il costrutto laggiù e mettilo ()dopo per costringerlo ad eseguire automaticamente.
tholdoldier,

Correzione. L'aggiunta ()alla fine della definizione __construct ha comunque comportato l'errore. Ho dovuto chiamare __construct();sulla propria linea come nel codice originale per evitare l'errore.
tholdoldier,

4

Forse è diventato un po 'più semplice, ma di seguito è quello che ho escogitato ora nel 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;
  }
}

Nell'usare la classe sopra, ho il seguente:

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());

Come puoi vedere, il costruttore accetta due parametri e impostiamo le proprietà dell'oggetto. Modifichiamo anche il colore e la forma dell'oggetto usando le setterfunzioni, e dimostriamo che il suo cambiamento è rimasto su chiamata getInfo()dopo questi cambiamenti.

Un po 'in ritardo, ma spero che questo aiuti. L'ho testato con un mochatest unitario e funziona bene.


3

Lo fanno se usi Typescript - open source da MicroSoft :-)

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

Typescript ti consente di creare falsi costrutti OO che vengono compilati in costrutti javascript. Se stai avviando un grande progetto, potrebbe farti risparmiare un sacco di tempo e ha appena raggiunto il traguardo della versione 1.0.

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

Il codice sopra viene 'compilato' per:

var BankAccount = (function () {
    function BankAccount(initially) {
        this.balance = initially;
    }
    BankAccount.prototype.deposit = function (credit) {
        this.balance += credit;
        return this.balance;
    };
    return BankAccount;
})();

Sto lavorando a un progetto di grandi dimensioni e sto cercando di convincere la gente che TypeScript ci darà delle riprese. Vedremo come va.
wootscootinboogie,

@wootscootinboogie In un giorno (che termina alle 5.30 in questo momento) mi sono trovato abbastanza lontano e abbastanza a mio agio con esso. Consiglio vivamente di leggere le specifiche e, mentre puoi saltare metà delle cose reali e grintose, ti stai facendo un favore leggendole almeno una volta. i video di questo ragazzo sono eccellenti youtube.com/user/basaratali/videos . buona fortuna)
Simon_Weaver,

1

In JavaScript il tipo di invocazione definisce il comportamento della funzione:

  • Invocazione diretta func()
  • Richiamo del metodo su un oggetto obj.func()
  • Invocazione del costruttorenew func()
  • Invocazione indiretta func.call()ofunc.apply()

La funzione viene invocata come costruttore quando si chiama usando l' newoperatore:

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

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

Qualsiasi istanza o oggetto prototipo in JavaScript ha una proprietà constructor, che fa riferimento alla funzione di costruzione.

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

Controlla questo post sulla proprietà del costruttore.


0

Mentre utilizzavo il grande modello di Blixt dall'alto, ho scoperto che non funziona bene con l'ereditarietà multi-livello (MyGrandChildClass che estende MyChildClass che estende MyClass) - scorre ciclicamente chiamando ripetutamente il costruttore del primo genitore. Quindi ecco una semplice soluzione: se hai bisogno di ereditarietà multi-livello, invece di usare l' this.constructor.super.call(this, surName);uso chainSuper(this).call(this, surName);con la funzione catena definita in questo modo:

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;
}

0

http://www.jsoops.net/ è abbastanza buono per oop in Js. Se forniscono funzioni e variabili private, protette, pubbliche e anche ereditarietà. Codice di esempio:

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

0

solo per offrire un po 'di varietà. ds.oop è un bel modo per dichiarare le classi con i costruttori in javascript. Supporta tutti i possibili tipi di ereditarietà (incluso 1 tipo che anche c # non supporta) così come le interfacce che sono belle.

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

0

Qui dobbiamo notare un punto nello script java, è un linguaggio senza classi, tuttavia possiamo ottenerlo utilizzando le funzioni nello script java. Il modo più comune per raggiungere questo obiettivo è necessario creare una funzione nello script java e utilizzare una nuova parola chiave per creare un oggetto e utilizzare questa parola chiave per definire proprietà e metodi. Di seguito è l'esempio.

// 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

-2

Nella maggior parte dei casi è necessario in qualche modo dichiarare la proprietà necessaria prima di poter chiamare un metodo che passa queste informazioni. Se non è necessario impostare inizialmente una proprietà, è possibile chiamare un metodo all'interno dell'oggetto in questo modo. Probabilmente non è il modo più carino di farlo, ma funziona ancora.

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.