Heim > Web-Frontend > js-Tutorial > Hauptteil

Wie Variablen in JavaScript gespeichert werden

伊谢尔伦
Freigeben: 2016-11-22 14:39:35
Original
3465 Leute haben es durchsucht

Grundprinzip

Variablen in js umfassen 5 Grundtypen und einen komplexen Datentyp Object. Natürlich sind häufig verwendete Funktionen und Arrays alle Objekte. Für Basistypen und komplexe Typen gibt es zwei verschiedene Speichermethoden: Stapelspeicher und Heapspeicher. Der Grund, warum zwei Speichermethoden implementiert werden, ist sehr einfach: Sobald der Grundtyp initialisiert ist, ist die Speichergröße festgelegt, und der Zugriff auf die Variable bedeutet den Zugriff auf die tatsächlichen Daten im Speicher der Variablen, was als Zugriff nach Wert bezeichnet wird . Der Objekttyp kann irgendwann seine Größe erhöhen und die Speichergröße ist nicht festgelegt. Beispielsweise führt das dynamische Hinzufügen von Objektattributen, das dynamische Erhöhen der Array-Größe usw. zu einer Vergrößerung der Variablen und kann nicht auf dem Stapel verwaltet werden. Daher legt js die Objekttypvariablen im Heap ab, sodass der Interpreter nach Bedarf Speicher dafür zuweisen und über den Referenzzeiger des Objekts darauf zugreifen kann. Da die Speicheradressengröße des Objekts im Heap festgelegt ist, ist dies möglich be Die Speicheradresse wird in einer Referenz zum Stapelspeicher gespeichert. Diese Methode wird als Referenzzugriff bezeichnet. Nun, es ist wichtig, dies zu verstehen, und Sie können viele Probleme bei der zukünftigen Programmierung vermeiden. Schauen wir uns den folgenden Code an:

var a = 'I am a string.';   //a,b,c的变量中保存的都是实际的值,因为他们是基本类型的变量
var b = 1010;
var c = false;
var d = a;    //d中保存着和“a值一样的副本,它们互不影响”
a = 'I am different from d';
alert(d);    //输出'I am a string'
Nach dem Login kopieren

Der obige Code ist leicht zu verstehen, d , und einander Es hat keinen Einfluss.“ Die Situation für den Zugriff per Referenz ist etwas anders:

var e = {
name : 'I am an object',
setName : function(name){
this.name = name;
}
};
var f = e;    //赋值操作,实际上的结果是e,f都是指向那个对象的引用指针
f.setName('I am different from e,I am object f.');
alert(e.name);    //对f进行操作,e的值也改变了!
Nach dem Login kopieren

Für die Referenztypzuweisung wird, um es ganz klar auszudrücken, der Zeiger des Objekts kopiert und die beiden Zeiger zeigen auf dasselbe. Es gibt keine Kopie eines Entitätsobjekts, es gibt immer noch nur ein Originalobjekt! Gut. Das Obige ist der größte und grundlegendste Unterschied zwischen Basistypen und Referenztypen! Ich verwende ein Bild, um es anschaulich auszudrücken:

Wie Variablen in JavaScript gespeichert werden

* Der Stapelspeicher speichert grundlegende Typvariablen und Objektzeiger; der Heap speichert Objekte Entity

Wie Variablen in JavaScript gespeichert werden

* Situationen im Stapel und Heap vor und nach dem Kopieren

Probleme durch Referenztypen

1 der Verwendung des Prototypmodells zum Erstellen von Objekten

Wir alle wissen, dass in JavaScript OO (Object Oriented) der größte Vorteil der Verwendung des Prototypmodells zum Erstellen von Objekten darin besteht, dass die Objektinstanzen die darin enthaltenen Attribute und Eigenschaften gemeinsam nutzen können die Prototyp-Methode. Dadurch werden die Mängel des Konstruktormusters vermieden, d. h. jedes Objekt verfügt über eine Kopie jeder Methode und jede Methode wird in jeder Instanz neu erstellt, wodurch die Wiederverwendung von Methoden bedeutungslos wird.

Nun, die Verwendung des Prototypmusters teilt Methoden für alle Instanzen, aber wenn es Eigenschaften mit Referenztypwerten im Prototyp gibt, treten Probleme auf:

var Person = function(){
};
Person.prototype = {
constructor : Person,
name : 'Hanzongze',
hobby : ['basketable', 'swiming', 'running'],    //注意,这里包含着一个引用类型的属性
sayName : function(){
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.hobby.push('music');
alert(person2.hobby);    //输出为'basketable', 'swiming', 'running','music'
alert(person1.hobby === person2.hobby);    //true
Nach dem Login kopieren

Da das Hobby-Attribut vorhanden ist Der Wert des Referenztyps, also das Hobby-Attribut der vom Person-Konstruktor erstellten Instanz, zeigt auf diese Referenzentität, und die Attribute zwischen Instanzobjekten stören sich gegenseitig. Dies ist nicht das gewünschte Ergebnis. Um diese Art von Problem zu vermeiden, besteht die Lösung darin, eine Kombination aus Konstruktormodell und Prototypmodell zu verwenden:

var Person = function(){
this.name = 'Hanzongze';
this.hobby = ['basketable', 'swiming', 'running'];    //对引用类型的值使用构造函数模式
};
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.hobby.push('music');
alert(person2.hobby);   //输出 'basketable', 'swiming', 'running',说明对person1的修改没有影响到person2
alert(person1.hobby === person2.hobby);    //false
Nach dem Login kopieren

Probleme bei der Prototypenvererbung

Dieses Problem ist im Wesentlichen das gleiche wie das vorherige, tritt jedoch im Zusammenhang mit der prototypischen Vererbung auf. Schauen wir uns ein Prototyp-Kettenvererbungsproblem an:

var Person = function(){
this.name = 'Hanzongze';
this.hobby = ['basketable', 'swiming', 'running'];
};
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
};
//子类型Student
function Student(){
}
Student.prototype = new Person();    //Student继承了Person
var student1 = new Student();
var student2 = new Student();
student1.hobby.push('music');    //对子类实例student1的引用属性做了改动
var student3 = new Student();
alert(student2.hobby);    //输出'basketable', 'swiming', 'running', 'music'
alert(student3.hobby);    //输出'basketable', 'swiming', 'running', 'music'
Nach dem Login kopieren

In diesem Code können Sie sehen, dass die Unterklasse Student von der übergeordneten Klasse Person erbt. Da jedoch die prototypische Vererbung verwendet wird, dh die Instanz der übergeordneten Klasse als Prototyp der Unterklasse dient, werden die Referenztypattribute in der Instanz auch im Prototyp-Prototyp der Unterklasse vererbt. Instanzen der Unterklasse teilen sich das Referenzattribut und beeinflussen sich gegenseitig.

Die Lösung besteht darin, die geliehene Konstruktorlösung zu verwenden (dies ist jedoch keine ideale Lösung. Die ideale Lösung besteht darin, eine Kombination aus Prototypkette und geliehenem Konstruktor zu verwenden. Dabei handelt es sich um viele Vererbungsmuster, die kurz beschrieben werden hier. Werde einen ausführlichen Artikel schreiben):

var Person = function(){
this.name = 'Hanzongze';
this.hobby = ['basketable', 'swiming', 'running'];
};
Person.prototype = {
constructor : Person,
sayName : function(){
alert(this.name);
}
};
function Student(){
//借用构造函数,继承了Person
Person.call(this);
}
var student1 = new Student();
var student2 = new Student();
student1.hobby.push('music');
alert(student2.hobby);    //输出'basketable', 'swiming', 'running', 'music'
Nach dem Login kopieren


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
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!