2013-04-19 9 views
22

Ich habe ein paar verschiedene Möglichkeiten gesehen, um Objekte in Javascript zu instanziieren, wollte die Vorteile/Nachteile der verschiedenen Ansätze kennen und warum Sie eine über die andere verwenden würden.Javascript erstellen Objekte - mehrere Ansätze, Unterschiede?

Ansatz 1

var obj = { 
    prop: value, 
    . 
    . 
    . 
} 

Ansatz ist Standardansatz, nichts Neues :)

Ansatz 2

var obj = new function() { 
    var prop1 = value1; 
    var fn1 = function() { 
    }; 
    . 
    . 
    . 

    this.prop2 = value2; 
    . 
    . 
    . 
}(); 

Die Funktion Ansatz, wollte ich diesen Ansatz vergleichen mit Ansatz 3. Der Funktionsansatz wird hauptsächlich zur Kapselung verwendet (korrekt?)

Ansatz 3

var obj = (function() { 
    var prop1 = value1; 
    var fn1 = function() { 
    }; 
    . 
    . 
    . 

    return { 
     prop2: value2, 
     . 
     . 
     . 
    } 
})(); 

Mit diesem Ansatz sehe ich nicht ganz die Gründe für seine Verwendung. Wie unterscheidet es sich von Ansatz 2? Beide können zum Verkapseln von Logik verwendet werden.

Ist es so, dass wir Parameter übergeben können, damit wir mit möglichen Konflikten umgehen können ?? ZB jQuery $ Syntax - aber Sie können dies auch mit Ansatz 2 ...

Vielen Dank.


Edit:


ich weiß der Ansatz 1 und 3 ähnlich sind (da sie beide Rückkehr Objekte) jedoch 3 nähern schafft auch eine Schließung. Welcher Ansatz 2 auch tut.

Das ist die Basis meiner Frage wirklich, sowohl 2 und 3 schaffen Schließungen, aber was ist der Unterschied zwischen ihnen.

+0

In Ansatz 2 sollte das Schlüsselwort 'new' nicht vorhanden sein. – Halcyon

+2

@FritsvanCampen - Ja sollte es. Dies erstellt ein neues Objekt aus der (anonymen) Konstruktorfunktion. –

+1

Wenn das Schlüsselwort 'new' nicht vorhanden ist, wäre es eine Klasse. – macool

Antwort

10

In den Ansätzen # 2 und # 3 wird die constructor Eigenschaft der resultierenden Objekte unterschiedlich sein.

In der Praxis bedeutet dies, dass der zweite Ansatz ermöglicht es Ihnen, mehr als ein Objekt mit der anonymen Konstruktorfunktion zu instanziiert:

x = new function() { alert(1) }; 
y = new x.constructor; // shows the message too 

Die Top-Antwort auf Module pattern vs. instance of an anonymous constructor enthält ein Zitat von Douglas Crockford, in dem er erklärt, warum er denkt, dass der Ansatz # 3 besser ist als # 2.

+0

Schön. Ich hatte nicht über die Konstruktoreigenschaft nachgedacht. –

0

Es gibt keinen großen Unterschied zwischen den Ansätzen 2 und 3 für einzelne Objekte. (Wenn Sie die in Ansatz 2 verwendete Funktion benennen würden, hätten Sie einen wiederverwendbaren Konstruktor definiert.) Mein Eindruck ist, dass Ansatz 3 häufiger für diese Situationen verwendet wird, aber ich sehe keinen großen Unterschied zwischen ihnen.

Es ist zu beachten, dass beide Ansätze 2 und 3 können Argumente:

var approach2Obj = new function(formalArg) { 
    var privateProp = ...; 
    this.publicProp = ...; 
    // more constructor logic 
)(actualArg); 

var approach3Obj = (function(formalArg) { 
    var privateProp = ...; 
    // more creation logic 
    return { 
     publicProp : ...; 
    }; 
}(actualArg)); 

P. S. Als @Alexey Lebedev points out in his answer, ein Unterschied zwischen den beiden (vielleicht der einzige) ist, dass approach2Obj.constructor und approach3Obj.constructor wird anders sein. approach3Obj.constructor wird identisch sein Object, während approach2Obj.constructor wird die anonyme Funktion sein.

+0

Sorry im Grunde ist die prop1 private Variablen anzugeben. Die Logik der Funktion kann fortfahren und diese Variablen verwenden ... Ich werde aktualisieren, um dies widerzuspiegeln – Umair

+0

@Umair - ich glaube nicht, dass sich meine Antwort ändert. Die Ansätze 2 und 3 sind grundsätzlich gleichwertig. –

4

Der erste und dritte Ansatz sind fast identisch, in einer Weise, dass beide ein Objektliteral erstellen, das ein direktes Kind der Klasse Object ist.Der Unterschied zwischen ihnen ist, dass in der dritten Ansatz können Sie irgendeine Art von Verkapselung von Eigenschaften haben:

var obj = (function() { 
    var prop = {}; 

    return { 
     prop2: function(){ return prop }; 
    } 
})(); 

Performance-weise Sie könnte prüfen, dass der dritte Ansatz Schließung schafft, während der erste nicht!

Im zweiten Ansatz erstellen Sie lediglich ein neues Objekt aus einer anonymen Klasse, die kein direktes Kind der Klasse Object ist.

Die richtige Form des zweiten Ansatzes ist dies (zumindest das ist ECMA-Standard):

var obj = new function() { 
    var prop1 = value1; 

    this.prop2 = value2; 
}(); 

Der Unterschied zwischen Ansatz 2 und 3 nur Kette ihr Erbe ist: (obj2 unter der Annahme von 2. Ansatz und obj3 ist vom 3. Ansatz)

obj2.__proto__ == Object.prototype; // false 
obj3.__proto__ == Object.prototype; // true 

obj2 wird von einem anonymen Klasse erstellt selbst:

obj2.__proto__.__proto__ == Object.prototype; // true (there's 2 level of inheritance here) 
+0

Was meinst du mit "direktes Kind"? –

+1

Beliebiges Objektliteral wird direkt von 'Object.prototype' geerbt, wodurch es direkt untergeordnet wird von der' Object' Klasse: 'obj .__ proto__ == Object.prototype' –

0

Ihre Frage sollte 2 Ansätze sein, weil Ansatz 3 ist genau wie Ansatz 1 nur die Art und Weise zu erstellen, dass durch Selbstausführungsfunktion ist.

Über den Unterschied, wenn Sie ein Objekt wie Ansatz 1 machen können Sie darüber nachdenken wie ein Objekt mit nur statische Funktion wie in Java. so ist es immer am Leben und du nicht Instanz daraus zu machen (ähnlich Singleton) - so, wenn Sie dieses Objekt machen:

var obj = { 
    prop: value, 
    func: function(){ 
    alert(this.prop); 
    } 
}; 

Sie können es sofort anrufen:

obj.prop = 'something else'; 
obj.func(); 

Ansatz 2 (ohne die neuen wie der Kommentar, den Sie bekommen haben) ist ein klassisches Objekt, das Sie Instanzen erstellen können - erben machen (mit js „Tricks“) und so weiter:

function Person(firstName,lastName){ // or var Person = function(... 
    this.firstName = firstName; 
    this.lastName= lastName; 

    this.getFullName = function(){ 
     return this.firstName + ' ' + this.lastName; 
    } 
} 

//use 
var person1 = new Person('yair','lapid'); 
var person2 = new Person('Naftali','Bennet'); 

you can put it in an array etc... 
var arr = [person1,person2, new Person('shelly','yekimovits')]; 
+0

Ansatz 3 erzeugt eine Schließung; Ansatz 1 nicht. Das macht sie ganz anders. –

+0

Aber das ist nicht die Frage - Sie können auch eine reguläre Funktion aufrufen, die ein Objekt oder ein Flugzeug zurückgibt, die ein Objekt zurückgeben - er fragt nach dem Unterschied der Erstellung von Objekten - und das ist nicht die richtige Definition von Schließung btw ... – Adidi

2

Ansatz 1
Dies ist ein einzelnes Objekt, keine Klasse und Sie leichter nicht definieren kann, wenn es

var obj = { 
    prop: value 
} 

Ansatz 2
Eine nicht anonyme Funktion komplex ist.Es wird ein Objekt aus einer ‚Klasse‘, erstellen normalle die Funktion als Klassennamen gespeichert und mehrere Objekte des gleichen Typs leicht wie unten erstellen:

var Bycicle= function() { 
    var prop1 = value1; 

    this.prop2 = value2; 
} 
var obj1 = new Bycicle(), 
    obj2 = new Bycicle(); 

Ansatz 3
Eine anonyme Funktion Variablen von außerhalb der Funktion kann nicht mit Variablen innerhalb der Funktion stören:

var a = 10; 
var obj = (function() { 
    alert(a); // Alerts undefined 
    var prop1 = value1; 
    alert(prop1); // alerts the value of value1 
    return { 
     prop2: value2; 
    } 
})(); // Within the() you can pass arguments to the anonymous function. 

Mehr über anonyme Funktionen: http://helephant.com/2008/08/23/javascript-anonymous-functions/

Andere Ansätze
Es gibt auch eine Object.create() und ein new Object() neue Objekte zu schaffen, die beide die gleiche wie Ansatz sind 1.

Fazit
Am Ende wird immer das Objekt sein, das gleiche, außer für die 3., weil es anonym ist.

0

Um Ansatz 2 zu verstehen, muss der Leser einige ziemlich technische Dinge über die Funktionsweise des neuen Schlüsselwortes wissen. Insbesondere, dass es die anonyme Funktion tatsächlich als Konstruktor bezeichnet, anstatt ein neues Funktionsobjekt zu instanziieren und es in der obj-Variablen abzulegen.

Um Ansatz 3 zu verstehen, muss der Leser nur das IIFE-Muster verstehen. Dieses Muster ist in den letzten zwei Jahren in JavaScript-Code sehr häufig geworden, und das ist wahrscheinlich der Grund, warum diese Version häufiger verwendet wird.

Beide Versionen werden verwendet, um Kapselung zu erzeugen, und beide Versionen erfordern das Verständnis einer komplexen Sprachfunktion. Das Sprachfeature, das im dritten Ansatz erforderlich ist, ist jedoch bekannter als das Sprachfeature, das zum Verständnis von Ansatz zwei erforderlich ist. Deshalb wird Ansatz 3 häufiger in freier Wildbahn verwendet.

+0

Ein Mitarbeiter entfernt einmal das Schlüsselwort "new" von einem anonymen Konstruktor, weil er dachte, es sei ein Tippfehler. –

2

Es gibt auch:

var obj = Object.create({prop: ...}); 

Dies funktioniert durch einen Prototyp zu setzen. Es ist viel effizienter, einen Prototyp zu verwenden, wenn mehrere Objekte Eigenschaften oder Methoden gemeinsam nutzen sollen.

var proto = {foo: function() {}}, 
    obj1 = Object.create(proto), 
    obj2 = Object.create(proto), 
    obj3 = {foo: function() {}}, 
    obj4 = {foo: function() {}}; 

In diesem Beispiel teilen obj1 und obj2 eine "foo" -Funktion, die in "proto" definiert ist. Inzwischen haben obj3 und obj4 jeweils ihr eigenes "foo". Wenn Sie viele Objekte mit vielen Eigenschaften erstellen, kann dies einen großen Unterschied beim Speicherverbrauch und sogar bei der Leistung bewirken.

Dieser Vorteil wird durch die Verwendung des Schlüsselworts "new" genutzt, wenn Sie eine benannte Funktion verwenden und dem Prototyp der Funktion Eigenschaften zuweisen (z. B. f.prototype.prop), bevor Sie new verwenden.

16

7 Möglichkeiten, Objekte in JavaScript zu erstellen:

1. Object-Konstruktor

Der einfachste Weg, um ein Objekt zu erstellen, ist die Object-Konstruktor zu verwenden: Ansicht plainprint?

var person = new Object(); 
person.name = "Diego"; 
person.getName = function(){ 
    return this.name; 
}; 

2. Literal Notation

Ansicht plainprint?

var person = { 
    person.name : "Diego", 
    person.getName : function(){ 
     return this.name; 
    } 
} 

3. Werks Funktion

Die Fabrik-Funktion ermöglicht die Logik für die Erstellung von ähnlichen Objekten zu kapseln und wiederverwenden. Es nutzt dafür alle vorherigen Konstrukte. Entweder: view plainprint?

var newPerson=function(name){ 
    var result = new Object(); 
    result.name = name; 
    result.getName = function(){ 
     return this.name; 
    }; 
    return result; 
}; 
var personOne = newPerson("Diego"); 
var personTwo = newPerson("Gangelo"); 
console.log(personOne.getName()); // prints Diego 
console.log(personTwo.getName()); // prints Gangelo 

Oder:

view plainprint? 
var newPerson=function(name){ 
    return { 
     person.name : name, 
     person.getName : function(){ 
      return this.name; 
     }; 
}; 
var personOne = newPerson("Diego"); 
var personTwo = newPerson("Gangelo"); 
console.log(personOne.getName()); // prints Diego 
console.log(personTwo.getName()); // prints Gangelo 

4. Funktion Constructor

In Javascript ist es möglich, jede Funktion mit dem neuen Betreiber vor, es zu nennen. Gegeben eine Funktion F, für neues F(): wird ein neues leeres Objekt X erzeugt. X wird als Kontext für F gesetzt, was bedeutet, dass durchgehend F auf X zeigt. X wird als Ergebnis von F angezeigt.

function Person(name){ 
     this.name = name; 
     this.getName = function(){ 
      return this.name; 
     }; 
}; 
var personOne = new Person("Diego"); 
console.log(personOne.getName()); // prints Diego 
console.log(personOne instanceOf Person); // prints true 
console.log(personOne.constructor === Person); // prints true 
console.log(personOne instanceOf Object); // prints true 

5. Prototype

Funktionen sind in Javascript ganz besonderes. Sie sind Objekte, sie können andere Objekte erstellen und erhalten automatisch ein Feld namens Prototyp. Ein Prototyp ist ein einfaches Objekt mit einem einzigen Feld namens Konstruktor, das auf die Funktion selbst verweist. Das Besondere daran ist, dass jedes Objekt, das durch eine Funktion erstellt wird, den Prototyp der Funktion erbt. ansicht plainprint?

function Person(){}; 
Person.prototype.name = "Diego"; 
var personOne = new Person(); 
var personTwo = new Person(); 
console.log(personOne.constructor == Person); // prints true 
console.log(personOne.name); // prints Diego 
console.log(personTwo.constructor == Person); // prints true 
console.log(personTwo.name); // prints Diego 

6. Funktion/Prototype Kombination

Die Funktion/Prototyp Kombination, wie Sie sich vorstellen können, nutzt die Vorteile beider Ansätze :) Ansicht plainprint?

function Person(name){ 
     this.name = name; 
}; 
Person.prototype.getName = function(){ 
      return this.name; 
     }; 
var personOne = new Person("Diego"); 
var personTwo = new Person("Filippo"); 
console.log(personOne.getName()); // prints Diego 
console.log(personTwo.getName()); // prints Filippo 
console.log(personOne.getName === personTwo.getName) //prints true 

7. Singleton

Manchmal können Sie sicherstellen möchten, dass nur eine Instanz einer bestimmten Klasse vorhanden ist. Um ein Singleton in Javascript zu erhalten, ist es so einfach, den Konstruktor gleichzeitig zu definieren und aufzurufen: view plainprint?

var singleton = new function(){ 
    this.name = "ApplicationName"; 
}; 
+0

Was bedeutet "Druckplatte ansehen?" sogar gemein? – Taurus

Verwandte Themen