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

686

Ich bevorzuge es, OOP in großen Projekten zu verwenden, wie dem, an dem ich gerade arbeite. Ich muss mehrere Klassen in JavaScript erstellen, aber wenn ich mich nicht irre, gibt es mindestens ein paar Möglichkeiten, dies zu tun. Was wäre die Syntax und warum würde es so gemacht werden?

Ich möchte die Verwendung von Bibliotheken von Drittanbietern vermeiden - zumindest zunächst.
Auf der Suche nach anderen Antworten fand ich den Artikel Objektorientierte Programmierung mit JavaScript, Teil I: Vererbung - Doc JavaScript , in dem die objektorientierte Programmierung in JavaScript behandelt wird. Gibt es einen besseren Weg, um Vererbung zu machen?

Karim
quelle
Hinweis: Dies ist ein Duplikat von stackoverflow.com/questions/355848
Jason S
3
Persönlich mag ich es, Klassenmitglieder innerhalb des Funktionskörpers zu deklarieren. Ich verwende die 'Fixing the This'-Technik, um einen Abschluss zu erstellen, damit er sich eher wie eine Klasse verhält. Ich habe ein detailliertes Beispiel in meinem Blog: ncombo.wordpress.com/2012/12/30/…
Jon
Ich habe den größten Teil der C ++ OOP-Funktionalität mit einer einfachen und natürlichen Syntax auf JavaScript portiert. Siehe meine Antwort hier: stackoverflow.com/a/18239463/1115652
In JavaScript gibt es keine Klassen. Wenn Sie jedoch ein klassenähnliches Verhalten in JS simulieren möchten, können Sie dies tun. Siehe Details in: symfony-world.blogspot.com/2013/10/…
ducin

Antworten:

743

So geht's, ohne externe Bibliotheken zu verwenden:

// Define a class like this
function Person(name, gender){

   // Add object properties like this
   this.name = name;
   this.gender = gender;
}

// Add methods like this.  All Person objects will be able to invoke this
Person.prototype.speak = function(){
    alert("Howdy, my name is" + this.name);
};

// Instantiate new objects with 'new'
var person = new Person("Bob", "M");

// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"

Jetzt ist die eigentliche Antwort viel komplexer. Zum Beispiel gibt es in JavaScript keine Klassen. JavaScript verwendet ein prototypeVererbungsschema auf Basis.

Darüber hinaus gibt es zahlreiche beliebte JavaScript-Bibliotheken, die ihren eigenen Stil zur Annäherung an klassenähnliche Funktionen in JavaScript haben. Sie sollten mindestens Prototype und jQuery ausprobieren .

Die Entscheidung, welche davon die "beste" ist, ist eine großartige Möglichkeit, einen heiligen Krieg gegen den Stapelüberlauf zu beginnen. Wenn Sie ein größeres JavaScript-lastiges Projekt starten, lohnt es sich auf jeden Fall, eine beliebte Bibliothek zu lernen und es auf ihre Weise zu tun. Ich bin ein Prototyp, aber Stack Overflow scheint sich zu jQuery zu neigen.

Soweit es nur "einen Weg gibt", ohne Abhängigkeiten von externen Bibliotheken, ist die Art und Weise, wie ich geschrieben habe, so ziemlich das Richtige.

Triptychon
quelle
48
Aber es funktioniert nicht wie in der X-Sprache, in der ich gelernt habe, wie ein Ding, mit dem Objektinstanzen erstellt werden, funktionieren sollte :(
Erik Reppen
2
Laut developer.mozilla.org/en-US/docs/Web/JavaScript/… sollten die Eigenschaften auch dem Prototyp hinzugefügt werden ("Person.prototype.name = '';")
DaveD
1
@ DaveD - vielleicht schon, scheint aber nicht mehr ..?
Kieren Johnstone
6
jQuery bietet nicht einmal die Möglichkeit, klassenähnliche Funktionen zu erstellen. (Alle Klassen sind CSS-Klassen.) Sie sollten sie aus diesem Teil der Antwort entfernen.
Bergi
7
Ab der zweiten Hälfte des Jahres 2015 wurde der neue Standard EcmaScript 6 veröffentlicht, daher schlage ich vor, ihn auf die neue Art und Weise (viel sauberer und einfacher) zu machen. Es6-features.org/#ClassDefinition
DevWL
213

Der beste Weg, eine Klasse in JavaScript zu definieren, besteht darin, keine Klasse zu definieren.

Ernsthaft.

Es gibt verschiedene Arten der Objektorientierung, einige davon sind:

  • klassenbasiertes OO (zuerst von Smalltalk eingeführt)
  • prototypbasiertes OO (zuerst von Self eingeführt)
  • multimethodenbasiertes OO (zuerst von CommonLoops eingeführt, denke ich)
  • prädikatenbasiertes OO (keine Ahnung)

Und wahrscheinlich andere, von denen ich nichts weiß.

JavaScript implementiert prototypbasiertes OO. In prototypbasiertem OO werden neue Objekte durch Kopieren anderer Objekte erstellt (anstatt aus einer Klassenvorlage instanziiert zu werden), und Methoden werden direkt in Objekten anstatt in Klassen ausgeführt. Die Vererbung erfolgt über die Delegierung: Wenn ein Objekt keine Methode oder Eigenschaft hat, wird es anhand seiner Prototypen (dh des Objekts, von dem es geklont wurde), der Prototypen des Prototyps usw. nachgeschlagen.

Mit anderen Worten: Es gibt keine Klassen.

JavaScript hat tatsächlich eine nette Optimierung dieses Modells: Konstruktoren. Sie können Objekte nicht nur erstellen, indem Sie vorhandene kopieren, sondern sie auch sozusagen "aus dem Nichts" konstruieren. Wenn Sie eine Funktion mit dem newSchlüsselwort aufrufen , wird diese Funktion zu einem Konstruktor, und das thisSchlüsselwort verweist nicht auf das aktuelle Objekt, sondern auf ein neu erstelltes "leeres". So können Sie ein Objekt beliebig konfigurieren. Auf diese Weise können JavaScript-Konstruktoren eine der Rollen von Klassen in herkömmlichem klassenbasiertem OO übernehmen: Sie dienen als Vorlage oder Blaupause für neue Objekte.

Jetzt ist JavaScript eine sehr leistungsfähige Sprache, so dass es recht einfach ist, ein klassenbasiertes OO-System in JavaScript zu implementieren, wenn Sie möchten. Sie sollten dies jedoch nur tun, wenn Sie es wirklich brauchen und nicht nur, weil Java es so macht.

Jörg W Mittag
quelle
"Wenn Sie eine Funktion mit dem neuen Schlüsselwort aufrufen, wird diese Funktion zu einem Konstruktor, und dieses Schlüsselwort verweist nicht auf das aktuelle Objekt, sondern auf ein neu erstelltes" leeres ". Wenn Sie eine Funktion ohne das neue Schlüsselwort aufrufen, bezieht sich dies auf den aufrufenden Kontext, standardmäßig auf das globale Objekt (Fenster). Im strengen Modus ist undefiniert die Standardeinstellung. call, apply and bind verwendet den aufrufenden Kontext als ersten Parameter. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Elias Hasle
83

ES2015 Klassen

In der ES2015-Spezifikation können Sie die Klassensyntax verwenden, die nur Zucker über dem Prototypsystem ist.

class Person {
  constructor(name) {
    this.name = name;
  }
  toString() {
    return `My name is ${ this.name }.`;
  }
}

class Employee extends Person {
  constructor(name, hours) {
    super(name);
    this.hours = hours;
  }
  toString() {
    return `${ super.toString() } I work ${ this.hours } hours.`;
  }
}

Leistungen

Der Hauptvorteil besteht darin, dass statische Analysewerkzeuge es einfacher finden, diese Syntax gezielt einzusetzen. Es ist auch für andere, die aus klassenbasierten Sprachen kommen, einfacher, die Sprache als Polyglot zu verwenden.

Vorsichtsmaßnahmen

Seien Sie vorsichtig bei den aktuellen Einschränkungen. Um private Eigenschaften zu erreichen, muss auf die Verwendung von Symbolen oder WeakMaps zurückgegriffen werden . In zukünftigen Versionen werden Klassen höchstwahrscheinlich um diese fehlenden Funktionen erweitert.

Unterstützung

Die Browserunterstützung ist derzeit nicht sehr gut (wird von fast allen außer IE unterstützt), aber Sie können diese Funktionen jetzt mit einem Transpiler wie Babel verwenden .

Ressourcen

Tal
quelle
56

Ich bevorzuge Daniel X. Moores {SUPER: SYSTEM}. Dies ist eine Disziplin, die Vorteile wie echte Instanzvariablen, traitbasierte Vererbung, Klassenhierarchien und Konfigurationsoptionen bietet. Das folgende Beispiel zeigt die Verwendung von echten Instanzvariablen, was meiner Meinung nach der größte Vorteil ist. Wenn Sie keine Instanzvariablen benötigen und nur mit öffentlichen oder privaten Variablen zufrieden sind, gibt es wahrscheinlich einfachere Systeme.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  return {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };
}

var fogel = Person({
  age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"

Wow, das ist für sich genommen nicht wirklich nützlich, aber sehen Sie sich das Hinzufügen einer Unterklasse an:

function Ninja(I) {
  I = I || {};

  Object.reverseMerge(I, {
    belt: "black"
  });

  // Ninja is a subclass of person
  return Object.extend(Person(I), {
    greetChallenger: function() {
      return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
    }
  });
}

var resig = Ninja({name: "John Resig"});

resig.introduce(); // "Hi I'm John Resig and I'm 25"

Ein weiterer Vorteil ist die Möglichkeit, Module und eine auf Merkmalen basierende Vererbung zu haben.

// The Bindable module
function Bindable() {

  var eventCallbacks = {};

  return {
    bind: function(event, callback) {
      eventCallbacks[event] = eventCallbacks[event] || [];

      eventCallbacks[event].push(callback);
    },

    trigger: function(event) {
      var callbacks = eventCallbacks[event];

      if(callbacks && callbacks.length) {
        var self = this;
        callbacks.forEach(function(callback) {
          callback(self);
        });
      }
    },
  };
}

Ein Beispiel für die Personenklasse ist das bindbare Modul.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  var self = {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };

  // Including the Bindable module
  Object.extend(self, Bindable());

  return self;
}

var person = Person();
person.bind("eat", function() {
  alert(person.introduce() + " and I'm eating!");
});

person.trigger("eat"); // Blasts the alert!

Offenlegung: Ich bin Daniel X. Moore und das ist mein {SUPER: SYSTEM}. Dies ist der beste Weg, um eine Klasse in JavaScript zu definieren.

Daniel X Moore
quelle
@DanielXMoore "Instanzvariablen werden von einzelnen Instanzen einer Klasse gemeinsam genutzt" Dies sind keine Instanzvariablen, sondern statische / Klassenvariablen.
JAB
2
@JAB Das ist falsch, statische / Klassenvariablen werden von allen Instanzen einer Klasse gemeinsam genutzt. Jede Instanz hat ihre eigenen Instanzvariablen.
Daniel X Moore
(Anders ausgedrückt, unter Verwendung der normalen Bedeutung des Begriffs "Instanzvariable", ob eine Variable eine Variable ist oder nicht, ist orthogonal zum Grad der Zugänglichkeit der Variablen.)
JAB
2
Sie klangen fast wie ein Superheld, weil Sie den besten xD
Dadan
Ein einfacher Ansatz, um eine Javascript-Klasse mit Javascript-Objekten zu definieren: wapgee.com/story/i/203
Ilyas karim
41
var Animal = function(options) {
    var name = options.name;
    var animal = {};

    animal.getName = function() {
        return name;
    };

    var somePrivateMethod = function() {

    };

    return animal;
};

// usage
var cat = Animal({name: 'tiger'});
Liammclennan
quelle
Dies ist eine sehr elegante Möglichkeit, eine verwendbare Objektstruktur zu erstellen, ohne etwas importieren zu müssen. Ich habe Resigs Klassensystem verwendet, aber das könnte mir besser gefallen. Vielen Dank.
Tim Scollick
29
Das Problem bei diesem Ansatz ist, dass jedes Mal, wenn Sie eine neue Animal-Instanz erstellen, die Funktionen neu definiert werden, anstatt sie nur einmal mit dem Prototyp zu definieren.
Justin
33

Im Folgenden finden Sie die Möglichkeiten zum Erstellen von Objekten in Javascript, 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 (). Bitte beziehen Sie sich auf [diesen 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();


Um die Antwort mit ES6 / ES2015 auf dem neuesten Stand zu halten

Eine Klasse ist 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());
Amol M Kulkarni
quelle
1
@ Justin: Bitte lassen Sie mich wissen, was nicht gültig ist?
Amol M Kulkarni
Während ich diese Notationen studierte, stieß ich auch auf this.set (). Zum Beispiel: this.set ('port', 3000). Ich vermute, dies wird verwendet, um die Port-Eigenschaft für das Objekt festzulegen. Wenn ja, warum verwenden wir nicht direkt: {port: 3000}. Gibt es Unterlagen, in denen ich weitere Einzelheiten erfahren kann?
Adityah
24

Ich denke, Sie sollten Douglas Crockfords Prototypal Inheritance in JavaScript und Classical Inheritance in JavaScript lesen .

Beispiele von seiner Seite:

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

Bewirken? Sie können Methoden auf elegantere Weise hinzufügen:

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

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

Ich empfehle auch seine Videos: Advanced JavaScript .

Weitere Videos finden Sie auf seiner Seite: http://javascript.crockford.com/ Im John Reisig-Buch finden Sie viele Beispiele auf der Website von Douglas Crockfor.

Jarek
quelle
25
Ist es nur ich Wie zum Teufel ist das eleganter? Ich würde Funktionsdefinitionen mit tatsächlichen 'strings'Namen viele Dinge nennen, aber elegant ist keine davon ...
Fgysin stellt Monica am
4
@JAB, aber Reflexion ist die Ausnahme, nicht die Regel. Bei der obigen Methode müssen Sie alle Ihre Methoden mit Zeichenfolgen deklarieren .
Kirk Woll
16

Weil ich den YUI / Crockford-Fabrikplan nicht zugeben werde 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'});

wo idealerweise die Art des Tests auf so etwas wie der ersten prototypisierten Methode ist

Annakata
quelle
Ich mag das. Ich verwende meistens die Standardsyntax von JS, weil mir die Idee, Funktionen in jede Objektinstanz zu kopieren, nicht gefällt. Ich habe die Schönheit einer in sich geschlossenen Lösung immer vermisst, und das löst sie ziemlich gut.
Lukasz Korzybski
1
Ich bin mir nicht sicher, aber ich habe verstanden, dass das Definieren einer Prototypfunktion innerhalb des Bereichs (etwas als Abschluss) einer Funktion zu einem Speicherverlust führt, da der Garbage Collector bei diesen Klassen nicht dorthin gelangen kann.
Sanne
15

Wenn Sie einfach vorgehen, können Sie das Schlüsselwort "new" vollständig vermeiden und einfach Factory-Methoden verwenden. Ich bevorzuge dies manchmal, weil ich JSON gerne zum Erstellen von Objekten verwende.

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 jedoch nicht sicher, wie hoch die Leistung bei großen Objekten ist.

Sam
quelle
Die Zeile obj.instancevar1 = var1 ist nicht erforderlich, da das innere Objekt Zugriff auf die Parameter von getSomeObj () hat.
Triptychon
Beeindruckend. Das macht mein Gehirn weh, aber es hat eine gewisse Eleganz. Der Teil "obj.instancevar1 = var1" ist also der Anfang einer Art Konstruktor, nehme ich an?
Karim
Ich habe gerade Triptychs Kommentar gesehen. Aha. Sie können also einfach so etwas wie "instancevar1: var1" ausführen, wobei das innere Objekt instanziiert wird.
Karim
Genau ... wenn Sie mit {} ein Objekt definieren, hat es Zugriff auf Variablen, die sich derzeit im Gültigkeitsbereich befinden.
Sam
10
Mit diesem Ansatz verlieren Sie die Fähigkeit zu erben, und da Sie obj.prototype.something nicht verwenden, definieren Sie die Funktionen jedes Mal, wenn Sie das Objekt verwenden = mehr Speicher und langsamer.
einige
12
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 die Klasse mit dem Konstruktor in JavaScript.

Mick
quelle
10

Der einfache Weg ist:

function Foo(a) {
  var that=this;

  function privateMethod() { .. }

  // public methods
  that.add = function(b) {
    return a + b;
  };
  that.avg = function(b) {
    return that.add(b) / 2; // calling another public method
  };
}

var x = new Foo(10);
alert(x.add(2)); // 12
alert(x.avg(20)); // 15

Der Grund dafür thatist, dass thisdies an etwas anderes gebunden sein kann, wenn Sie eine Methode als Ereignishandler angeben, sodass Sie den Wert während der Instanziierung speichern und später verwenden.

Bearbeiten: Es ist definitiv nicht der beste Weg, nur ein einfacher Weg. Ich warte auch auf gute Antworten!

orip
quelle
1
Das that = this Konstrukt ist hier nicht notwendig. Außerdem werden die Methoden add () und avg () für jede "Instanz" der Klasse Foo kopiert, anstatt von ihnen gemeinsam genutzt zu werden.
Triptychon
1
Ist es in diesem Fall notwendig (sorta), aber nicht der einfache Fall, den Sie angegeben haben.
Triptychon
9

Sie möchten wahrscheinlich einen Typ mithilfe des Faltmusters erstellen:

    // Here is the constructor section.
    var myType = function () {
        var N = {}, // Enclosed (private) members are here.
            X = this; // Exposed (public) members are here.

        (function ENCLOSED_FIELDS() {
            N.toggle = false;
            N.text = '';
        }());

        (function EXPOSED_FIELDS() {
            X.count = 0;
            X.numbers = [1, 2, 3];
        }());

        // The properties below have access to the enclosed fields.
        // Careful with functions exposed within the closure of the
        // constructor, each new instance will have it's own copy.
        (function EXPOSED_PROPERTIES_WITHIN_CONSTRUCTOR() {
            Object.defineProperty(X, 'toggle', {
                get: function () {
                    var before = N.toggle;
                    N.toggle = !N.toggle;
                    return before;
                }
            });

            Object.defineProperty(X, 'text', {
                get: function () {
                    return N.text;
                },
                set: function (value) {
                    N.text = value;
                }
            });
        }());
    };

    // Here is the prototype section.
    (function PROTOTYPE() {
        var P = myType.prototype;

        (function EXPOSED_PROPERTIES_WITHIN_PROTOTYPE() {
            Object.defineProperty(P, 'numberLength', {
                get: function () {
                    return this.numbers.length;
                }
            });
        }());

        (function EXPOSED_METHODS() {
            P.incrementNumbersByCount = function () {
                var i;
                for (i = 0; i < this.numbers.length; i++) {
                    this.numbers[i] += this.count;
                }
            };
            P.tweak = function () {
                if (this.toggle) {
                    this.count++;
                }
                this.text = 'tweaked';
            };
        }());
    }());

Dieser Code gibt Ihnen einen Typ namens myType . Es wird interne private Felder haben, die als Toggle und Text bezeichnet werden . Es wird auch diese exponierten Mitglieder haben: die Felder zählen und Zahlen ; die Eigenschaften wechseln , Text und numberLength ; die Methoden incrementNumbersByCount und tweak .

Das Faltmuster wird hier ausführlich beschrieben: Javascript-Faltmuster

unerschrocken
quelle
3

Code Golf für die Antwort von @ liammclennan .

var Animal = function (args) {
  return {
    name: args.name,

    getName: function () {
      return this.name; // member access
    },

    callGetName: function () {
      return this.getName(); // method call
    }
  };
};

var cat = Animal({ name: 'tiger' });
console.log(cat.callGetName());

tponthieux
quelle
2

MooTools (My Object Oriented Tools) konzentriert sich auf die Idee von Klassen . Sie können sogar mit Vererbung erweitern und implementieren.

Wenn es gemeistert wird, entsteht ein lächerlich wiederverwendbares, leistungsstarkes Javascript.

Ryan Florence
quelle
2

Objektbasierte Klassen mit Vererbung

var baseObject = 
{
     // Replication / Constructor function
     new : function(){
         return Object.create(this);   
     },

    aProperty : null,
    aMethod : function(param){
      alert("Heres your " + param + "!");
    },
}


newObject = baseObject.new();
newObject.aProperty = "Hello";

anotherObject = Object.create(baseObject); 
anotherObject.aProperty = "There";

console.log(newObject.aProperty) // "Hello"
console.log(anotherObject.aProperty) // "There"
console.log(baseObject.aProperty) // null

Einfach, süß und erledigt.

Ulad Kasach
quelle
1

Eine Basis

function Base(kind) {
    this.kind = kind;
}

Eine Klasse

// Shared var
var _greeting;

(function _init() {
    Class.prototype = new Base();
    Class.prototype.constructor = Class;
    Class.prototype.log = function() { _log.apply(this, arguments); }
    _greeting = "Good afternoon!";
})();

function Class(name, kind) {
    Base.call(this, kind);
    this.name = name;
}

// Shared function
function _log() {
    console.log(_greeting + " Me name is " + this.name + " and I'm a " + this.kind);
}

Aktion

var c = new Class("Joe", "Object");
c.log(); // "Good afternoon! Me name is Joe and I'm a Object"
Mikael Dúi Bolinder
quelle
1

Am Beispiel des Triptychons könnte dies sogar einfacher sein:

    // Define a class and instantiate it
    var ThePerson = new function Person(name, gender) {
        // Add class data members
        this.name = name;
        this.gender = gender;
        // Add class methods
        this.hello = function () { alert('Hello, this is ' + this.name); }
    }("Bob", "M"); // this instantiates the 'new' object

    // Use the object
    ThePerson.hello(); // alerts "Hello, this is Bob"

Dies erstellt nur eine einzelne Objektinstanz, ist jedoch weiterhin nützlich, wenn Sie eine Reihe von Namen für Variablen und Methoden in einer Klasse kapseln möchten. Normalerweise gibt es keine "Bob, M" -Argumente für den Konstruktor, beispielsweise wenn die Methoden ein System mit eigenen Daten aufrufen würden, z. B. eine Datenbank oder ein Netzwerk.

Ich bin noch zu neu bei JS, um zu sehen, warum dies das prototypeDing nicht benutzt .

Roland
quelle
0

JavaScript ist objektorientiert , unterscheidet sich jedoch grundlegend von anderen OOP- Sprachen wie Java, C # oder C ++. Versuche nicht, es so zu verstehen. Wirf das alte Wissen raus und fange von vorne an. JavaScript braucht ein anderes Denken.

Ich würde vorschlagen, ein gutes Handbuch oder etwas zu diesem Thema zu bekommen. Ich selbst fand ExtJS-Tutorials am besten für mich, obwohl ich das Framework vor oder nach dem Lesen nicht verwendet habe. Aber es gibt eine gute Erklärung dafür, was was in der JavaScript-Welt ist. Entschuldigung, es scheint, dass dieser Inhalt entfernt wurde. Hier ist stattdessen ein Link zur Kopie von archive.org . Funktioniert heute. : P.

Vilx-
quelle
2
Objektorientierter? Ich fand es funktionell .
Peter Mortensen
Der Link "ExtJS Tutorials" ist defekt.
Peter Mortensen
Ich denke, es wäre erklärender zu erklären, dass Funktionen in Javascript Objekte sind, und die Bracket-Scope-Regeln von Javascript machen jeden Funktionsblock einkapselnd.
Mibbit
-1

//new way using this and new
function Persons(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

var gee=new Persons("gee");
gee.greeting();

var gray=new Persons("gray");
gray.greeting();

//old way
function createPerson(name){
 var obj={};
 obj.name=name;
 obj.greeting = function(){
 console.log("hello I am"+obj.name);
 }; 
  return obj;
}

var gita=createPerson('Gita');
gita.greeting();

Avinash Maurya
quelle