이틀 전 kraaas
님의 기본 데이터 유형과 참조 유형의 차이점에 대한 글을 보고 정말 잘 쓴 글이라 생각해서 평소에 사용하던 것을 추가해볼까 하는 생각이 들었습니다. 몇 가지 지식 포인트와 이해를 보았으므로 다음 기사가 있습니다
js 기본 데이터 유형에는 정의되지 않음, null, 숫자, 부울이 포함됩니다. , 문자열. 기본 데이터 유형은 값으로 액세스됩니다. 즉, 변수에 저장된 실제 값에 대해 연산을 수행할 수 있습니다.
문자열과 같은 기본 유형의 값을 변경합니다:
var name = "change"; name.substr();//hang console.log(name);//change var s = "hello"; s.toUpperCase()//HELLO; console.log(s)//hello
이 두 예를 통해 원래 정의된 변수 이름의 값은 변경되지 않았으며 substr() 및 toUpperCase( ) 메소드는 원래 정의된 변수 이름과 아무 관련이 없는 새 문자열을 반환합니다.
다음과 같은 질문이 있는 사람들이 있을 수 있습니다. 코드를 살펴보세요.
var name = "change"; name = "change1"; console.log(name)//change1
값은 다음과 같습니다. 실제로 var name = "change", 여기서 기본 유형은 문자열, 즉 "change"이고 여기서 "change"는 변경할 수 없으며 name은 "change"를 가리키는 포인터일 뿐입니다. . 포인터가 가리키는 것은 변경될 수 있으므로 name = "change1"을 가리킨다. 마찬가지로 여기의 "change1"도 변경할 수 없다
당신이 생각하는 변화는 단지 "포인터가 변화를 가리키는 것"일 뿐입니다
여기서의 기본형은 이름이 아니라 "변화"를 의미하므로 명확하게 구분해야 합니다
var p = "change"; p.age = 29; p.method = function(){console.log(name)}; console.log(p.age)//undefined console.log(p.method)//undefined
위의 코드를 통해 기본 타입에는 속성과 메소드를 추가할 수 없다는 사실을 알 수 있었고, 기본 타입은 불변임을 다시 한번 증명했습니다
한 변수에서 다른 변수로 기본 유형 값을 할당하면 변수 개체에 새 값이 생성되고, 그 값은 새 변수에 할당된 위치에 복사됩니다.
var a = 10; var b = a; a++; console.log(a)//11 console.log(b)//10
위 코드에서 a에 저장된 값은 10입니다. a의 값을 사용하여 b를 초기화하면 b에도 값 10이 저장됩니다. 그러나 b에 10이 저장되고 a에 10이 저장됩니다. b의 값은 의 A 복사본에 있는 값을 알고 있습니다. 따라서 이 두 변수는 서로 영향을 주지 않고 모든 작업에 참여할 수 있습니다.
var person1 = '{}'; var person2 = '{}'; console.log(person1 == person2); // true
다음과 같은 기본 유형의 변수가 있는 경우:
var name = "jozo"; var city = "guangzhou"; var age = 22;
그러면 저장 구조는 다음과 같습니다.
스택 영역에는 변수의 식별자와 변수의 값이 포함됩니다.
JS에서는 위의 기본 유형 외에도 Object, Array, Function, Data 등과 같은 참조 유형도 객체라고 할 수 있습니다.
var o = {x:1}; o.x = 2;//通过修改对象属性值更改对象 o.y = 3;再次更改对象,给它增加一个属性 var a = [1,2,3]; a[0] = 0;//更改数组的一个元素 a[3] = 4;//给数组增加一个元素
var person = {}; person.name = "change"; person.say = function(){alert("hello");} console.log(person.name)//change console.log(person.say)//function(){alert("hello");}
우선 다음 코드에서:
var a = {}; var b= a; a.name = "change"; console.log(a.name)//change; console.log(b.name)//change b.age = 29; console.log(a.age)//29 console.log(b.age)//29
한 변수의 참조 유형 값을 다른 변수에 할당하는 경우 동시에 변수에 저장된 객체의 값도 새 변수에 할당된 공간에 복사됩니다. 참조형이 변수에 저장하는 것은 힙 메모리에 있는 객체의 주소이므로 기본 데이터형과 다르며, 이 값의 복사본은 실제로 포인터이며, 이 포인터는 다음을 가리킨다. 힙 메모리에 저장된 개체 그런 다음 할당 작업 후 두 변수는 모두 동일한 개체 주소를 저장하고 두 주소는 동일한 An 개체를 가리킵니다. 따라서 변수를 변경하면 서로 영향을 받습니다.
이들의 관계는 다음과 같습니다.
따라서 참조 유형의 할당은 실제로 객체입니다. 스택 영역에 저장된 주소 포인터의 할당이므로 두 변수는 다음을 가리킵니다. 동일한 개체이며 모든 작업은 서로 영향을 미칩니다.
var person1 = {}; var person2 = {}; console.log(person1 == person2)//false
두 객체가 완전히 똑같아 보이지만 같지 않은 이유는 무엇입니까?
참조 유형 비교는 참조 비교이기 때문에, 즉 이때 힙 메모리를 가리키는 스택 영역에 저장된 두 객체의 주소가 같은지 비교하는 것입니다. , p1과 p2는 모두 동일한 "{}"으로 보이지만 스택 영역에 저장하는 힙 메모리를 가리키는 주소가 다르기 때문에 두 객체는 동일하지 않습니다.
引用类型的存储需要在内存的栈区和堆区共同完成,栈区保存变量标识符和指向堆内存的地址
假如有以下几个对象:
var person1 = {name:"change1"}; var person2 = {name:"change2"}; var person3 = {name:"change3"};
则这三个对象在内存中保存的情况如下图:
先看下以下代码:
var s1 = "helloworld"; var s2 = s1.substr(4);
上面我们说到字符串是基本数据类型,不应该有方法,那为什么这里s1可以调用substr()呢?
通过翻阅js权威指南第3.6章节和高级程序设计第5.6章节我们得知,ECMAScript还提供了三个特殊的引用类型Boolean,String,Number.我们称这三个特殊的引用类型为基本包装类型,也叫包装对象.
也就是说当读取string,boolean和number这三个基本数据类型的时候,后台就会创建一个对应的基本包装类型对象,从而让我们能够调用一些方法来操作这些数据.
所以当第二行代码访问s1的时候,后台会自动完成下列操作:
创建String类型的一个实例;// var s1 = new String(“helloworld”);
在实例上调用指定方法;// var s2 = s1.substr(4);
销毁这个实例;// s1 = null;
正因为有第三步这个销毁的动作,所以你应该能够明白为什么基本数据类型不可以添加属性和方法,这也正是基本装包类型和引用类型主要区别:对象的生存期.使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都是一直保存在内存中.而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。
以上就是JavaScript 基本数据类型和引用类型的区别详解 的内容,更多相关内容请关注PHP中文网(www.php.cn)!
相关文章: