Heim > Web-Frontend > js-Tutorial > Hauptteil

Tutorial zum objektorientierten JavaScript

黄舟
Freigeben: 2016-12-20 15:23:47
Original
771 Leute haben es durchsucht

Javascript ist eine C-ähnliche Sprache. Ihre objektorientierten Dinge sind im Vergleich zu C++/Java seltsam, aber sie ist tatsächlich ziemlich mächtig. In den letzten zwei Tagen hat mich ein ehemaliger Kollege nach der objektorientierten Programmierung in Javascript gefragt, daher möchte ich einen Artikel schreiben, den er lesen kann. In diesem Artikel geht es hauptsächlich darum, die objektorientierte Programmierung in Javascript aus einer Gesamtperspektive zu erklären . Neu gepostet aus einem Artikel von Cool Shell, sehr gut geschrieben...

Darüber hinaus basiert dieser Artikel hauptsächlich auf ECMAScript 5 und zielt darauf ab, neue Technologien einzuführen. Bezüglich der Kompatibilität lesen Sie bitte den letzten Abschnitt.

Vorstudie

Wir wissen, dass die Definition von Variablen in Javascript grundsätzlich wie folgt lautet:

var name = 'Chen Hao';;

var email = 'haoel( @)hotmail.com';

var website = 'http://coolshell.cn';

Wenn Sie es in Objekte schreiben möchten, würde es so aussehen dies:

var chenhao = {

Name:'Chen Hao',

E-Mail: 'haoel(@)hotmail.com',

Website : 'http://coolshell .cn'

}

Ich kann also so zugreifen:

//Als Mitglied

chenhao. name;

chenhao.email;

chenhao.website;

//In Form einer Hash-Karte

chenhao["name"];

chenhao[ "email"];

chenhao["website"];

Was Funktionen betrifft, wissen wir, dass Javascript-Funktionen wie folgt aussehen:

 var doSomething = function(){

alert('Hello World.');

};

Also können wir das tun:

 var sayHello = function(){

var hello = „Hallo, ich bin „+ this.name

+“, meine E-Mail lautet: „ + this.email

+ „, meine Website ist: “ + this.website;

alert(hello);

};

//Direkte Zuweisung, das ist C/C++ sehr ähnlich Funktionszeiger

chenhao.Hello = sayHello;

chenhao.Hello();

Ich glaube, diese Dinge sind relativ einfach und jeder versteht sie. Sie können sehen, dass die JavaScript-Objektfunktion direkt deklariert, direkt zugewiesen und direkt verwendet wird. Dynamische Sprache für die Laufzeit.

Es gibt auch eine standardisiertere Schreibweise:

//Wir können sehen, dass die Funktion als Klasse verwendet wird.

var Person = function(name, email, website){

this.name = name;

this.email = email;

this. website = website;

this.sayHello = function(){

var hello = „Hallo, ich bin „+ this.name +“, n“ +

„meine E-Mail ist: ” + this.email + „, n“ +

“meine Website ist: ” + this.website;

alert(hallo);

};

};

var chenhao = new Person(“Chen Hao”, “haoel@hotmail.com”,

“http://coolshell.cn“ ; 🎜>In den obigen Beispielen können wir die folgenden Punkte sehen:

◆ Die Daten- und Mitgliederkapselung von Javascript ist sehr einfach. Keine Klasse ist vollständig eine Objektoperation. Rein dynamisch!

◆ Der This-Zeiger in der Javascript-Funktion ist entscheidend. Wenn nicht, handelt es sich um eine lokale Variable oder lokale Funktion.

◆ Javascript-Objekt-Memberfunktionen können bei Verwendung vorübergehend deklariert und ihnen direkt eine globale Funktion zugewiesen werden.

◆ Javascript-Mitgliedsfunktionen können in der Instanz geändert werden, was bedeutet, dass das Verhalten desselben Funktionsnamens in verschiedenen Instanzen möglicherweise nicht das gleiche ist.

 Eigenschaftskonfiguration – Object.defineProperty

Schauen Sie sich zunächst den folgenden Code an:

 //Objekt erstellen

var chenhao = Object.create(null) ;

//Legen Sie eine Eigenschaft fest

Object.defineProperty( chenhao,

'name', { value: 'Chen Hao',

writable: true ,

konfigurierbar: true,

aufzählbar: true });

//Mehrere Eigenschaften festlegen

Object.defineProperties( chenhao,

{

'email' : { value: 'haoel@hotmail.com',

beschreibbar: wahr,

konfigurierbar: wahr,

aufzählbar: wahr },

'website': { Wert: 'http://coolshell.cn',

beschreibbar: wahr,

konfigurierbar: wahr,

enumerable: true }

}

);

Lassen Sie uns darüber sprechen, was diese Attributkonfigurationen bedeuten.

beschreibbar: Ob der Wert dieses Attributs geändert werden kann.

konfigurierbar: Ob die Konfiguration dieses Attributs geändert werden kann.

enumerable: Ob diese Eigenschaft in einer for...in-Schleife durchlaufen oder in Object.keys aufgezählt werden kann.

Wert: Attributwert.

get()/set(_value): Accessoren abrufen und festlegen.

Get/Set-Accessor

In Bezug auf den Get/Set-Accessor bedeutet dies, dass get/set zum Ersetzen des Werts verwendet wird (er kann nicht mit dem Wert verwendet werden:

).

 var age = 0;

Object.defineProperty( chenhao,

'age', {

get: function() {return age+1;},

set: function(value) {age = value;}

aufzählbar: wahr,

konfigurierbar: wahr

}

);

chenhao.age = 100; //Call set

alert(chenhao.age); //Call get und Ausgabe 101 (+1 in get);

Sehen wir uns ein praktischeres Beispiel an – die Verwendung vorhandener Attribute (Alter) zum Erstellen neuer Attribute (Geburtsjahr) durch get und set:

 Object.defineProperty(chenhao,

'birth_year',

{

get: function() {

var d = new Date();

var y = d.getFullYear( );

return ( y – this.age );

},

set: function(year) {

var d = new Date();

var y = d.getFullYear();

this.age = y – Jahr;

}

}

);

alert(chenhao.birth_year);

chenhao.birth_year = 2000;

alert(chenhao.age);

Das scheint ein bisschen mühsam zu sein. Sagen Sie mir, warum schreibe ich es nicht so:

var chenhao = {

Name: „Chen Hao“,

E-Mail: „haoel@hotmail.com“,

Website: „http://coolshell.cn“,

age : 100,

getbirth_year() {

var d = new Date();

var y = d.getFullYear();

return ( y – this.age );

},

setbirth_year(year) {

var d = new Date();

var y = d.getFullYear();

this.age = y – Jahr;

}

};

alert(chenhao.birth_year) ;

chenhao.birth_year = 2000;

alert(chenhao.age);

Ja, Sie können dies tun, aber Sie können diese Dinge über defineProperty() tun:

1) Legen Sie Attributkonfigurationen wie beschreibbar, konfigurierbar, aufzählbar usw. fest.

2) Fügen Sie einem Objekt dynamisch Attribute hinzu. Zum Beispiel: einige HTML-DOM-Objekte.

Objekteigenschaftskonfiguration anzeigen

Wenn Sie diese Konfigurationen von Objekten anzeigen und verwalten, gibt es unten ein Programm, das die Eigenschaften und Konfiguration von Objekten ausgeben kann:

// Liste Objekte Eigenschaften.

function listProperties(obj)

{

var newLine = ”
“;

var name = Object.getOwnPropertyNames(obj );

for (var i = 0; i < Namen.Länge; i++) {

var prop = Namen[i];

document.write(prop + newLine);

// Listen Sie die Eigenschaftskonfiguration (Deskriptor) des Objekts mit der Funktion getOwnPropertyDescriptor auf.

var descriptor = Object.getOwnPropertyDescriptor(obj, prop);

for (var attr in descriptor) {

document.write(“…” + attr + ': ' + descriptor[attr]);

document.write(newLine);

}

document.write(newLine);

}

}

listProperties(chenhao);

 call, apply, bind and this

Der this-Zeiger von Javascript ist C++/Java sehr ähnlich . Schauen wir uns ein Beispiel an: (Dieses Beispiel ist sehr einfach, ich werde nicht mehr sagen)

 function print(text){

document.write(this.value + ' – ' + text+ '
');

}

var a = {value: 10, print : print};

var b = {value: 20, print : print};

print('hello');// this => global, Ausgabe „undefiniert – hallo“

a.print('a');// this => ; a, Ausgabe „10 – a“

b.print('b'); // this => b, Ausgabe „20 – b“

a['print' ] ('a'); // this => a, Ausgabe „10 – a“

Der Unterschied zwischen diesen beiden Funktionen besteht darin, dass sie unterschiedlich aussehen Das andere ist, dass die Leistung anders ist und die Leistung von apply viel schlechter ist. (Für die Leistung können Sie zu JSPerf gehen und einen Blick darauf werfen)

print.call(a, 'a'); // this => a, Output „10 – a“

print.call(b, 'b'); // this => b, Ausgabe „20 – b“

print.apply(a, ['a']); a, Ausgabe „10 – a“

print.apply(b, ['b']); // this => b, Ausgabe „20 – b“

Aber in bind Schließlich , dieser Zeiger kann unterschiedlich sein, aber weil Javascript dynamisch ist. Wie im folgenden Beispiel

var p = print.bind(a);

p('a'); // this => >

p.call(b, 'b'); // this => a, Ausgabe „10 – b“

p.apply(b, ['b']); this => a, Ausgabe „10 – b“

Vererbung und Überladung

Durch die obigen Beispiele können wir tatsächlich über Object.create() erben, siehe den Code unten, Student erbt von Object.

var Person = Object.create(null);

Object.defineProperties

(
Person,
{
'name' : { value: 'Chen Hao'},
'email' : { value : 'haoel@hotmail.com'},
'website': { value: 'http://coolshell.cn'}
}
);

Person.sayHello = function () {

var hello = „

Hallo, ich bin „+ this.name +“,
“ +
“mein E-Mail lautet: „+ this.email +“,
>}

var Student = Object.create(Person);
Student.no = „1234567“; //Student number
Student.dept = „Computer Science“

//Verwenden Sie die Attribute von Person
document.write(Student.name + ' ' + Student.email + ' ' + Student.website +'
');

/ /Person-Methode verwenden

Student.sayHello();

// Überladen Sie die SayHello-Methode
Student.sayHello = function (person) {
var hello = „

Hallo, ich bin „+ this.name +“,

„meine E-Mail ist:“ + this.email + „,
“ +
„meine Website ist:“ + this.website + „,
“ nein ist: „ + dies. nein + „,
“ +
„meine Abteilung ist:“ + dies.
}
//
Student.sayHello() erneut aufrufen;

//Student-Attribute anzeigen (nur no, dept und überladen sayHello)

document.write('

' + Object.keys(Student) + '
');


Anhand des obigen Beispiels können wir sehen, dass die Attribute in Person nicht tatsächlich nach Student kopiert werden, wir aber darauf zugreifen können. Dies liegt daran, dass Javascript diesen Mechanismus mithilfe von Delegaten implementiert. Tatsächlich ist dies der Prototyp, und Person ist der Prototyp von Student.

Wenn unser Code ein Attribut benötigt, prüft die Javascript-Engine zunächst, ob das aktuelle Objekt dieses Attribut hat. Wenn nicht, prüft sie, ob ihr Prototype-Objekt dieses Attribut hat, und fährt fort, bis ein Prototyp vorliegt Objekt gefunden wird oder bis keine Prototypobjekte mehr vorhanden sind.

Um dies zu beweisen, können wir Object.getPrototypeOf() verwenden, um Folgendes zu überprüfen:

Student.name = 'aaa';

//Output aaa

document.write ('

' + Student.name + '

');
//Ausgabe Chen Hao
document.write('

' +Object.getPrototypeOf(Student). name + '

');

Sie können also auch die Funktion des übergeordneten Objekts in der Funktion des untergeordneten Objekts aufrufen, genau wie Base::func() in C++. Wenn wir also die Hello-Methode überladen, können wir den Code der übergeordneten Klasse verwenden, wie unten gezeigt:

//Neue Version der überladenen SayHello-Methode

Student.sayHello = function (person) {

Object.getPrototypeOf(this).sayHello.call(this);
var hello = „meine Schülernummer ist:“ + diese Nr. + „,
“ +
„meine Abteilung ist:“ + this. dept;
document.write(hello + '
');
}

Das ist sehr mächtig.

Kombination

Das obige Ding kann unsere Anforderungen nicht erfüllen. Wir können hoffen, dass diese Objekte wirklich kombiniert werden können. Warum Kombination? Weil wir alle wissen, dass dies das Wichtigste im OO-Design ist. Allerdings unterstützt dies Javascript nicht besonders gut, sodass wir es trotzdem hinbekommen.

Zuerst müssen wir eine Kompositionsfunktion definieren: (Ziel ist das Objekt, das darauf wirkt, Quelle ist das Quellobjekt). Der folgende Code ist sehr einfach. Er entfernt nur die Attribute Quelle nacheinander und definiert sie als Ziel.

 function Composition(target, source)

{

var desc = Object.getOwnPropertyDescriptor;

var prop = Object.getOwnPropertyNames;

var def_prop = Object.defineProperty;

prop(source).forEach(

function(key) {

def_prop(target, key, desc(source, key ))

}

)

Rücklaufziel;

}

Mit dieser Funktion können wir hier jetzt spielen:

//Artist

var Artist = Object.create(null);

Artist.sing = function() {
return this.name + ' fängt an zu singen…';
}
Artist.paint = function() {
return this.name + ' beginnt zu malen…';
}

//Athlete

var Sporter = Object.create (null);

Sporter.run = function() {
return this.name + ' beginnt zu laufen…';
}
Sporter.swim = function() {
return this.name + ' beginnt schwimmen…';
}

Composition(Person, Artist);

document.write(Person.sing() + '
');

document .write(Person .paint() + '
');

Composition(Person, Sporter);

document.write(Person.run() + '
') ;

document.write(Person.swim() + '
');

//Sehen Sie, was in Person ist? (Ausgabe: sayHello,sing,paint,swim,run)

document.write('

' + Object.keys(Person) + '
'');


Prototyp und Vererbung

Lass uns zuerst über Prototypen sprechen. Schauen wir uns zunächst die folgende Routine an. Diese Routine ist dem Funktionszeiger in der C-Sprache sehr ähnlich.

var plus = function(x,y){

document.write( x + ' + ' + y + ' = ' + (x+y) + '
');

return x + y;
};

var minus = function(x,y){

document.write(x + ' – ' + y + ' = ' + (x-y) + '
');

return x – y;
};

var operation = {

'+': plus,

'-': minus
};

var calcule = function(x, y, operation){

return operation[operation](x, y);

};

calculate(12 , 4, '+');

calculate(24, 3, '-');


Können wir diese Dinge also kapseln? Schauen Sie sich das folgende Beispiel an:

 var Cal = function(x, y){

this.x = x;

this.y = y;

}

Cal.prototype.operations = {

'+': function(x, y) { return x+y;},

'-': function(x, y) { return x-y;}

};

Cal.prototype.calculate = function(operation){

return this.operations[operation](this.x, this. y);

};

var c = new Cal(4, 5);

c.calculate('+');

c .calculate('-');

Dies ist die Verwendung von Prototypen. Prototypen sind der wichtigste Inhalt in der JavaScript-Sprache. Es gibt zu viele Artikel im Internet zu diesem Thema. Um es ganz klar auszudrücken: Der Prototyp besteht darin, ein Objekt zu erweitern. Sein Merkmal besteht darin, eine neue Instanz durch „Kopieren“ einer vorhandenen Instanz zurückzugeben, anstatt eine neue Instanz zu erstellen. Die kopierte Instanz ist das, was wir als „Prototyp“ bezeichnen, und dieser Prototyp ist anpassbar (natürlich gibt es hier keine echte Kopie, es handelt sich eigentlich nur um eine Delegation). Im obigen Beispiel haben wir die Instanz Cal um ein Operations-Attribut und eine Berechnungsmethode erweitert.

Auf diese Weise können wir die Vererbung über diese Funktion implementieren. Denken Sie an unsere erste Person. Das folgende Beispiel besteht darin, eine Student-Person zu erstellen, um sie zu erben.

Funktion Person(Name, E-Mail, Website){
this.name = name;
this.email = email;
this.website = website;
};

Person.prototype.sayHello = function(){
var hello = „Hallo, ich bin „+ this.name +“,
“ +
“meine E-Mail lautet: „ + this .email + „,
“ +
„meine Website ist:“ + this.website;
return hello;
};

function Student(name, email, website , no, dept){
var proto = Object.getPrototypeOf;
proto(Student.prototype).constructor.call(this, name, email, website);
this.no = no;
this.dept = dept;
}

//Prototyp erben
Student.prototype = Object.create(Person.prototype);

//Konstruktor zurücksetzen
Student.prototype.constructor = Student;

//Overload sayHello()
Student.prototype.sayHello = function(){
var proto = Object.getPrototypeOf;
var hello = proto (Student.prototype).sayHello.call(this) + '
';
Hallo += „meine Schülernummer ist:“ + diese Nr. + „,
“ meine Abteilung ist: ” + this. dept;
return hallo;
};

var me = new Student(

„gtfx“,
“gtfx0209@gmail .com“ ,
"http://dyygtfx.com",
"12345678",
"Computer Science"
);
document.write(me.sayHello());

Kompatibilität

Die oben genannten Codes können möglicherweise nicht in allen Browsern ausgeführt werden, da die oben genannten Codes den ECMAScript 5-Spezifikationen folgen. In der Browserkompatibilitätsliste von ECMAScript 5 können Sie die „ES5-Browserkompatibilität“ sehen Tabelle" hier.

Der gesamte Code in diesem Artikel wurde auf der neuesten Version von Chrome getestet.

Im Folgenden sind einige Funktionen aufgeführt, die in Browsern verwendet werden können, die nicht mit ES5 kompatibel sind:

Object.create()-Funktion

 function clone(proto) {

function Dummy() { }

Dummy.prototype = proto;

Dummy.prototype.constructor = Dummy;

return new Dummy(); Äquivalent in Object.create(Person);

}

var me = clone(Person);

defineProperty() function

function defineProperty(target , Schlüssel, Deskriptor) {

if (descriptor.value){

target[key] = descriptor.value;

}else {

descriptor . get && target.__defineGetter__(key, descriptor.get);

descriptor.set && target.__defineSetter__(key, descriptor.set);

}

return target

}

keys() function

Function keys(object) { var result, key

result = [];

for (Objekt eingeben){

if (object.hasOwnProperty(key)) result.push(key)

}

Ergebnis zurückgeben;

}

Object.getPrototypeOf() function

Function proto(object) {

return !object? null

: '__proto__' in object? . __proto__

: /* nicht verfügbar? */ object.constructor.prototype

Bind-Funktion

 var Slice = [].slice

function bind(fn,bound_this) { varbound_args

bound_args = Slice.call(arguments, 2)

return function() { var args

args =bound_args.concat(slice.call(arguments))

return fn.apply(bound_this, args) }

}

Das Obige ist der Inhalt des objektorientierten JavaScript-Tutorials. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage