it-swarm.com.de

javascript: Funktion und Objekt ...?

Kannst du eine Funktion als Objekt bezeichnen? Zum Beispiel:

function Tip(txt){      
    this.content = txt;  
    this.shown = false;  
}

Und:

var tip = new Tip(elem.attr('title'));

Meine Fragen: 

  1. Können Sie new für eine Funktion wie für ein Objekt aufrufen? 
  2. Die Verwendung von "this" wird ermöglicht, weil wir use that als Objekt fungieren?
41
Paul

Sie suchen das Konzept constructor .

Alle Funktionen in JavaScript sind Objekte und können zum Erstellen von Objekten verwendet werden:

function make_person(firstname, lastname, age) {
    person = {};
    person.firstname = firstname;
    person.lastname = lastname;
    person.age = age;
    return person;
}
make_person("Joe", "Smith", 23);
// {firstname: "Joe", lastname: "Smith", age: 23}

Um jedoch neue Objekte eines bestimmten Typs zu erstellen (dh einen Prototyp zu erben, einen Konstruktor zu haben usw.), kann eine Funktion auf this und verweisen, wenn sie mit new aufgerufen wird. operator gibt dann ein Objekt mit allen Attributen zurück, die für this in der Funktion definiert sind - this verweist in solchen Fällen auf das neue Objekt, das wir erstellen.

function make_person_object(firstname, lastname, age) {
    this.firstname = firstname;
    this.lastname = lastname;
    this.age = age;
    // Note, we did not include a return statement
}

Der Hauptunterschied zwischen make_person und make_person_object besteht darin, dass der Aufruf von new make_person() (im Gegensatz zu einfach make_person()) nichts anderes bewirkt ... beide erzeugen dasselbe Objekt . Wenn Sie jedoch make_person_object() ohne den Operator new aufrufen, werden Ihre this-Attribute für das aktuelle this-Objekt definiert (im Allgemeinen window, wenn Sie im Browser arbeiten).

Somit:

var Joe = make_person_object("Joe", "Smith", 23);
console.log(Joe); // undefined
console.log(window.firstname) // "Joe" (oops)

var John = new make_person_object("John", "Smith", 45);
console.log(John); // {firstname: "John", lastname: "Smith", age: 45}

Wie @RobG hervorhebt, wird durch diese Vorgehensweise ein Verweis auf die Eigenschaft prototype von make_person_object für jede von uns erstellte "Person" erstellt. Dies ermöglicht es uns, Personen Methoden und Attribute nachträglich hinzuzufügen:

 // Assuming all that came before
make_person_object.prototype.full_name = "N/A";
make_person_object.prototype.greet = function(){ 
    console.log("Hello! I'm", this.full_name, "Call me", this.firstname); 
};
John.full_name // "N/A"
John.full_name = "John Smith"; 
make_person_object.full_name // Still "N/A"
John.greet(); // "Hello! I'm John Smith Call me John"

Konvention besagt, dass Konstruktorfunktionen wie make_person_object großgeschrieben, singularisiert und "nominiert" sind (mangels eines besseren Ausdrucks) - daher hätten wir einen Person -Konstruktor anstelle eines make_person_object, der falsch sein könnte für eine gewöhnliche Funktion.

Siehe auch:

120
Sean Vieira

Jede Funktion hat einen Verweis auf this. Wenn Sie Tip() aufrufen, verweist this auf das globale Objekt. Wenn Sie new Tip() aufrufen, wird ein neues Objekt mit einem Verweis auf Tip.prototype erstellt, und this verweist auf dieses neue Objekt.

Sie können new nicht für Objekte verwenden, beispielsweise new {} löst TypeError: object is not a function aus. Wenn Sie sich auf new Object() beziehen, funktioniert das, da Object eine Funktion ist.

17
Adam Bergmark

Ja. In JavaScript ist alles technisch ein Objekt. Wenn Sie new verwenden, erstellt es eine Instanz des Tip-Objekts und ruft dann die Tip-Funktion auf, als wäre es ein Konstruktor.

Wenn Sie dem Tip-Objekt Funktionen hinzufügen möchten, sollten Sie sie wie folgt zum Prototyp von Tip hinzufügen:

Tip.prototype.getContent = function() {
    return this.content;
};

Wenn Sie das haben, dann tun Sie:

var tip = new Tip("this  is my content.");
alert(tip.getContent());

Daraufhin wird eine Nachricht angezeigt, die besagt, "das ist mein Inhalt."

Sie können new jedoch nur verwenden, wenn das Objekt über eine funktionale Implementierung verfügt. Das funktioniert also nicht:

var Tip = { content: txt, show: false };
var tipObj = new Tip();
6
Tom Chandler

Ich habe seit fast 8 Jahren (2008-2016) Probleme, diese Konzepte (Funktionen als Objekte, Prototypobjekte, __proto__-Eigenschaft, Konstruktoreigenschaft) zu verstehen. Zuerst habe ich David Flanagan "JavaScript Definitive Guide 5/6th ed" für 4-5 Jahre nach mehreren Lesungen der Kapitel 6,8,9 gestartet. es machte für mich keinen Sinn, aber nachdem ich mich im Internet angestrengt hatte, konnte ich einige Funktionen (typische C++ - Funktion mit Eigenschaften) als Objekte verwalten. weil das Objekt auch Methoden haben kann. Und glücklicherweise habe ich im siebten Jahr 2015 Wrox Nicholas C. Zakas "Professional JavaScript for Web Developers 3rd ed" Kapitel 6,7; und es war wirklich sehr hilfreich, die vier Begriffe zu verstehen. Traditionell wird in C/C++/C # angenommen, dass Funktionen ein Objekt modifizieren; oder mit anderen Worten, sie sind für das "Tun von etwas" gemacht, wobei "Objekte" gemacht werden, um den Status eines globalen laufenden Kontexts mit Methoden aufrechtzuerhalten, um seinen eigenen Objektstatus zu ändern. Wenn Funktionen also erstklassige Objekte sein können, warum können Objekte nicht wie Funktionen sein?

Die Hauptfrage sollte hier WARUM sein? Warum nicht einzelne konzeptuelle Entität wie "assoziative Funktion" oder "verkettete Argumente"? Und hier ist mein Verständnis: Browser Exe ist eine Single-Threaded-Anwendung, und diese Exe steuert den Aufruf des JS-Interpreters mit vordefinierter Gültigkeitsbereichskette (einige ähneln einer Befehlsfolge mit Argumenten). Zur Laufzeit lädt die JS-Engine (nicht der Interpreter) den Code auf Hub-Art und Weise (da es keine Hauptmethode gibt, die die gut definierten, mit einem Schlüssel versehenen Codes und ihren Aufruf erhebt). Wenn Funktionen in diesem Code nicht als Objekte behandelt werden, müssen sie in separaten Aufrufkontexten (außerhalb der Gültigkeitsbereichskette) verwaltet werden. Dies ist in c/c ++/c # (bcoz von Multithread und unbegrenztem Speicher), aber nicht in JS problemlos möglich . Daher macht "to-do smth on chained object" ein Java-Skript zum Objekt erster Klasse. Tatsächlich machen JS-Objekte dasselbe; Der einzige Unterschied besteht darin, dass "Aufruf eines Objekts" nicht in Objekten vorhanden ist, bei denen als "Aufruf einer Funktion" ein sinnvoller geketteter Kontext vorliegt. Funktionen können auch als "eine Reihe von Variablen mit Assemblersprache-Anweisungen mit Adressverknüpfung (Kette)" betrachtet werden. Der Verknüpfungsteil ist eine andere Seite der Geschichte, als Top-> Bottom-Linking (Prototypobjekt) vs. Bottom-> TopLinking (__ proto__-Eigenschaft) vs. Objekt-Blue-Print-> Objektinstanzen (Konstruktoreigenschaft). Vor ein paar Monaten fand ich das folgende Bild als hilfreich, um die Verknüpfung zu verstehen.

http://judis.me/wordpress/wp-content/uploads/2015/08/JavaScriptDiagram.png "JS-Objektmodell"

3
Saurabh

Die Funktion fungiert als Konstruktor für eine Klasse. Alternativ können Sie Folgendes tun:

function Tip(txt) {
 return {
 content: txt,
 shown: false
}
}

und rufen Sie eine neue Instanz mit: var myTip = new Tip("my epic tip"); .__ auf. Dies ähnelt etwa c #:

public class Tip {
string text = "";
public Tip(string txt) {
text = txt;
}
}

Also irgendwie. 1) Sie rufen new auf, da die Funktion im Wesentlichen als Klasse fungiert und 2) this auf die aktuelle Instanz der Klasse verweist. 

1
Thomas Shields

für # 1: Es gibt ein Objekt namens Function (Großbuchstabe F)

var f = neue Funktion ("x", "y", "return x * y;");

für # 2: Das "this" unterscheidet sich je nach Innococation-Muster (wie von Douglas Crockford bezeichnet). Crockford sagte, dass es 4 Muster gibt (Methodenmuster, Funktionsmuster, Konstruktormuster und "Anwenden" -Muster).

1
user670800
  1. In der Tat sind alle Datentypen, wie z. B. Array, Funktionen Objekte.
  2. Wenn wir die Funktion als Klassendeklaration übernehmen, funktioniert dies.
0
xblymmx