JavaScript에서 변수가 저장되는 방식

伊谢尔伦
풀어 주다: 2016-11-22 14:39:35
원래의
3465명이 탐색했습니다.

기본 원리

js의 변수에는 5가지 기본 유형과 복잡한 데이터 유형인 Object가 포함됩니다. 물론 일반적으로 사용되는 함수와 배열은 모두 객체입니다. 기본 유형과 복합 유형의 경우 스택 저장과 힙 저장이라는 두 가지 저장 방법이 있습니다. 두 가지 저장 방식을 구현한 이유는 아주 간단합니다. 즉, 일단 기본형이 초기화되면 메모리 크기는 고정되고, 변수에 접근한다는 것은 변수의 메모리에 있는 실제 데이터에 접근한다는 뜻인데, 이를 값에 의한 접근이라고 합니다. . 객체 유형은 어느 시점에서 크기가 증가할 수 있으며 메모리 크기는 고정되어 있지 않습니다. 예를 들어, 객체의 속성을 동적으로 추가하거나 배열의 크기를 동적으로 늘리는 등의 작업은 변수의 크기를 늘리며 스택에서 유지 관리할 수 없습니다. 따라서 js는 객체 유형 변수를 힙에 배치하여 인터프리터가 필요에 따라 메모리를 할당하고 객체의 참조 포인터를 통해 액세스할 수 있도록 합니다. 힙에 있는 객체의 메모리 주소 크기가 고정되어 있기 때문입니다. be 메모리 주소는 스택 메모리에 대한 참조에 저장됩니다. 이 방법을 참조에 의한 액세스라고 합니다. 글쎄, 이것을 이해하는 것이 중요하며 향후 프로그래밍에서 많은 문제를 피할 수 있습니다. 다음 코드를 살펴보자.

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'
로그인 후 복사

위 코드는 이해하기 쉽다. 즉, 값 copy로 접근하는 변수는 "네 것이 네 것, 내 것이 내 것, 우리 모두 복사본을 가지고 있다"는 것이다. , 서로 영향을 미치지 않습니다." 참조에 의한 액세스의 상황은 약간 다릅니다.

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的值也改变了!
로그인 후 복사

참조 유형 할당의 경우 직설적으로 말하면 객체의 포인터가 복사되고 두 포인터는 동일한 것을 가리킵니다. 엔터티 개체의 복사본은 없으며 원본 개체는 여전히 하나만 있습니다! 좋은. 위의 내용이 기본형과 참조형의 가장 크고 근본적인 차이점입니다! 생생하게 표현하기 위해 그림을 사용합니다.

JavaScript에서 변수가 저장되는 방식

* 스택 메모리에는 기본 유형 변수와 객체 포인터가 저장됩니다. 힙에는 객체가 저장됩니다.

JavaScript에서 변수가 저장되는 방식

* 복사 전후의 스택 및 힙 상황

참조 유형에 따른 문제

1. 프로토타입 모델을 사용하여 객체를 생성하는 방법

우리 모두는 JavaScript OO(객체 지향)에서 프로토타입 모델을 사용하여 객체를 생성할 때의 가장 큰 이점은 객체 인스턴스가 객체에 포함된 속성과 속성을 공유할 수 있다는 것을 알고 있습니다. 프로토타입 방법. 이렇게 하면 생성자 패턴의 단점을 피할 수 있습니다. 즉, 각 객체는 각 메서드의 복사본을 갖고 각 메서드는 각 인스턴스에서 다시 생성되므로 메서드 재사용이 의미가 없게 됩니다.

글쎄, 프로토타입 패턴을 사용하면 모든 인스턴스에 대해 메서드를 공유하지만 프로토타입에 참조 유형 값을 가진 속성이 있는 경우 문제가 발생합니다.

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
로그인 후 복사

hobby 속성이 다음과 같기 때문에 참조 유형의 값이므로 Person 생성자가 생성한 인스턴스의 취미 속성은 이 참조 엔터티를 가리키며 인스턴스 개체 간의 속성은 서로 간섭합니다. 이는 우리가 원하는 결과가 아닙니다. 해결 방법은 생성자 모델과 프로토타입 모델의 조합을 사용하는 것입니다.

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
로그인 후 복사

2. 프로토타입 상속 문제

이 문제의 본질은 사실 이전 문제와 동일하지만 프로토타입 상속의 맥락에서 발생합니다. 프로토타입 체인 상속 문제를 살펴보겠습니다.

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'
로그인 후 복사

이 코드에서 하위 클래스 Student가 상위 클래스 Person으로부터 상속받는 것을 볼 수 있습니다. 그러나 프로토타입 상속이 사용되기 때문에, 즉 상위 클래스의 인스턴스가 하위 클래스의 프로토타입 역할을 하므로 인스턴스의 참조 유형 속성도 하위 클래스의 프로토타입 프로토타입에 상속됩니다. 하위 클래스의 인스턴스는 참조 속성을 공유하고 서로 영향을 미칩니다.

해결책은 차용 생성자 솔루션을 사용하는 것입니다(그러나 이상적인 솔루션은 아닙니다. 이상적인 솔루션은 프로토타입 체인과 차용 생성자를 조합하여 사용하는 것입니다. 여기에는 많은 상속 패턴이 포함됩니다. 자세한 내용은 여기에 간략하게 설명하겠습니다):

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'
로그인 후 복사


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!