707 Stimmen

Welche Techniken können verwendet werden, um eine Klasse in JavaScript zu definieren, und was sind ihre Nachteile?

Ich ziehe es vor, OOP in großen Projekten wie dem, an dem ich gerade arbeite, zu verwenden. Ich muss mehrere Klassen in JavaScript erstellen, aber wenn ich mich nicht irre, gibt es zumindest ein paar Möglichkeiten, das zu tun. Wie sieht die Syntax aus und warum sollte man es auf diese Weise tun?

Ich möchte die Verwendung von Bibliotheken von Drittanbietern vermeiden - zumindest am Anfang.
Auf der Suche nach weiteren Antworten fand ich den Artikel Objektorientierte Programmierung mit JavaScript, Teil I: Vererbung - Doc JavaScript das die objektorientierte Programmierung in JavaScript behandelt. Gibt es einen besseren Weg, um Vererbung durchzuführen?

1 Stimmen

Hinweis: Dies ist ein Duplikat von stackoverflow.com/questions/355848

3 Stimmen

Ich persönlich mag es, Klassenmitglieder innerhalb des Funktionskörpers zu deklarieren. Ich verwende die Technik des "Fixierens des This", um einen Abschluss zu erstellen, der sich mehr wie eine Klasse verhält. Ich habe ein ausführliches Beispiel in meinem Blog: ncombo.wordpress.com/2012/12/30/

1 Stimmen

Ich habe die meisten C++ OOP-Funktionen mit einer einfachen und natürlichen Syntax auf JavaScript portiert. Siehe meine Antwort hier: stackoverflow.com/a/18239463/1115652

37voto

Amol M Kulkarni Punkte 20152

Im Folgenden sind die Möglichkeiten, Objekte in Javascript zu erstellen, die ich bisher verwendet habe

Beispiel 1:

obj = new Object();
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}

Beispiel 2:

obj = {};
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}
obj.sayHello();

Beispiel 3:

var obj = function(nameParam) {
    this.name = nameParam;
}
obj.prototype.sayHello = function() {
    console.log('Hello '+ this.name);
}

Beispiel 4: Tatsächliche Vorteile von Object.create(). siehe [dieser Link]

var Obj = {
    init: function(nameParam) {
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var usrObj = Object.create(Obj);  // <== one level of inheritance

usrObj.init('Bob');
usrObj.sayHello();

Beispiel 5 (angepasstes Crockford's Object.create):

Object.build = function(o) {
   var initArgs = Array.prototype.slice.call(arguments,1)
   function F() {
      if((typeof o.init === 'function') && initArgs.length) {
         o.init.apply(this,initArgs)
      }
   }
   F.prototype = o
   return new F()
}
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}  // For example

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var bob = Object.build(userB, 'Bob');  // Different from your code
bob.sayHello();

Antwort mit ES6/ES2015 auf dem neuesten Stand halten

Eine Klasse wird wie folgt definiert:

class Person {
    constructor(strName, numAge) {
        this.name = strName;
        this.age = numAge;
    }

    toString() {
        return '((Class::Person) named ' + this.name + ' & of age ' + this.age + ')';
    }
}

let objPerson = new Person("Bob",33);
console.log(objPerson.toString());

1 Stimmen

@Justin: Bitte teilen Sie mir mit, was nicht gültig ist?

0 Stimmen

Beim Studium dieser Notationen bin ich auch über this.set() gestolpert. Zum Beispiel: this.set('port', 3000). Ich vermute, dass damit die Port-Eigenschaft für das Objekt festgelegt wird. Wenn ja, warum verwenden wir dann nicht direkt: {port: 3000}. Gibt es eine Dokumentation, in der ich mehr Details finden kann?

23voto

Jarek Punkte 5645

Ich denke, Sie sollten Douglas Crockfords Prototypische Vererbung in JavaScript y Klassische Vererbung in JavaScript .

Beispiele von seiner Seite:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

Wirkung? Er ermöglicht es Ihnen, Methoden auf elegantere Weise hinzuzufügen:

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

Ich empfehle auch seine Videos: Fortgeschrittenes JavaScript .

Weitere Videos finden Sie auf seiner Seite: http://javascript.crockford.com/ In John Reisigs Buch finden Sie viele Beispiele von Douglas Crockfors Website.

25 Stimmen

Geht es nur mir so? Wie zum Teufel kann das eleganter sein? Ich würde Funktionsdefinitionen mit tatsächlichen 'strings' nennt viele Dinge, aber elegant ist keines davon...

4 Stimmen

@JAB, aber Reflexion ist die Ausnahme, nicht die Regel. Mit der obigen Methode müssen Sie deklarieren Sie alle Ihre Methoden mit Saiten.

16voto

annakata Punkte 72408

Da ich den YUI/Crockford-Fabrikplan nicht zulassen will und weil ich die Dinge gerne in sich geschlossen und erweiterbar halte, ist dies meine Variante:

function Person(params)
{
  this.name = params.name || defaultnamevalue;
  this.role = params.role || defaultrolevalue;

  if(typeof(this.speak)=='undefined') //guarantees one time prototyping
  {
    Person.prototype.speak = function() {/* do whatever */};
  }
}

var Robert = new Person({name:'Bob'});

wobei der typeof-Test idealerweise auf etwas wie die erste prototypische Methode angewendet wird

0 Stimmen

Ich mag es. Ich verwende meistens die Standardsyntax von JS, weil ich die Idee, Funktionen in jede Objektinstanz zu kopieren, nicht mag. Ich habe immer die Schönheit der in sich geschlossenen Lösung vermisst, obwohl, und dies löst es ziemlich gut.

1 Stimmen

Ich bin mir nicht sicher, aber ich habe verstanden, dass das Definieren von Prototyp-Funktionen innerhalb des Geltungsbereichs (sozusagen als Abschluss) einer Funktion zu einem Speicherleck führt, da der Garbage Collector in der Instanz dieser Klassen nicht dorthin gelangen kann.

14voto

Sam Punkte 5797

Wenn Sie sich für Einfachheit entscheiden, können Sie das Schlüsselwort "new" ganz vermeiden und nur Factory-Methoden verwenden. Ich bevorzuge dies manchmal, weil ich gerne JSON verwende, um Objekte zu erstellen.

function getSomeObj(var1, var2){
  var obj = {
     instancevar1: var1,
     instancevar2: var2,
     someMethod: function(param)
     {  
          //stuff; 
     }
  };
  return obj;
}

var myobj = getSomeObj("var1", "var2");
myobj.someMethod("bla");

Ich bin mir allerdings nicht sicher, wie groß die Leistungseinbußen bei großen Objekten sind.

0 Stimmen

Die Zeile obj.instancevar1 = var1 ist nicht notwendig, da das innere Objekt Zugriff auf die Parameter von getSomeObj() hat.

0 Stimmen

Wow. Das bereitet mir Kopfschmerzen, aber es hat eine gewisse Eleganz. Der Teil "obj.instancevar1 = var1" ist also der Anfang einer Art Konstruktor, nehme ich an?

0 Stimmen

Ich habe gerade den Kommentar von Triptych gesehen. Verstehe ich. Also, Sie könnten einfach etwas wie "instancevar1: var1" tun, wo das innere Objekt instanziiert wird.

12voto

Mick Punkte 6650
var Student = (function () {
    function Student(firstname, lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.fullname = firstname + " " + lastname;
    }

    Student.prototype.sayMyName = function () {
        return this.fullname;
    };

    return Student;
}());

var user = new Student("Jane", "User");
var user_fullname = user.sayMyName();

Auf diese Weise kompiliert TypeScript Klassen mit Konstruktoren in JavaScript.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X