1.概念
ECMAScript包含两个不同类型的值:基本类型值和引用类型值。基本类型值指的是简单的数据段;引用类型值指由多个值构成的对象。当我们把变量赋值给一个变量时,解析器首先要做的就是确认这个值是基本类型值还是引用类型值。
常见的值类型有:
Boolean、Number和String。这五种基本数据类型可以直接操作保存在变量中的实际值。
常见的引用类型有:
Array、Function、Object
空的数据类型有:
Null、Undefined
javascript引用数据类型是保存在堆内存中的对象,与其它语言不同的是,你不可以直接访问堆内存空间中的位置和操作堆内存空间。只能通过操作对象的在栈内存中的引用地址。所以引用类型的数据,在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存在堆内存中的对象。
2.区别:2.1区别一
JavaScript中的值类型的值是不可变的:
任何方法都无法改变值类型的值。数字、布尔值和字符串等都属于不可变类型。比如,修改一个数值的内容,本身就说不通。虽然字符串可以被看成是由字符组成的数组,可能会被认为是可变的。但是,在JavaScript中,字符串是不可变的。在实际操作过程中,可以访问字符串任意位置的文本,单JavaScript并未提供修改已知字符串的文本内容的方法。
varstr='abcd';
console.log(str.toUpperCase());//ABCD
console.log(str);//abcd
可见,原始的str字符串值并未发生改变,仍然是小写的abcd,第二行代码,只是调用了字符串的toUpperCase()方法后,返回的是一个新的字符串。
JavaScript中的引用类型的值是可变的:
varstudent={
'name':'张三',
'age':20
}
console.log(student.name);
student.name='李四';
console.log(student.name);
疑问:如果像studen.name = '李四'这段代码一样,给str也做相同的操作,str的值不也是改变了吗?
扩展:如果给str重新赋值,那么改变的是变量的值,给str重新赋值了,并没有改变字符串内容,改变的只是变量str的内容。
2.2区别二
JavaScript中的值类型无法添加属性和方法:
varstudent='张三';
student.age=26;
student.run=function(){
console.log('running');
}
console.log(student.age);//undefined
console.log(student.run);//undefined
通过代码示例,可知,不能给值类型添加属性和方法。从而,也更加说明了值类型是不可变的。
JavaScript中的引用类型可以添加属性和方法:
varstudent={}
student.age=26,
student.run=function(){
console.log('running');
}
console.log(student.age);//26
console.log(student.run);/*function(){
console.log('running');
}*/
2.3区别三
JavaScript中的值类型的变量是存放在栈区的:
JavaScript中的引用类型的变量也是存放在栈区的,不同的是,引用类型在栈区中存放的是变量标识符以及变量所对应值得引用地址,而变量所对应的值被存放在堆区中:
2.4区别四
JavaScript中的值类型的比较是值的比较:
JavaScript中的值类型在进行比较的时候,只有在它们的值相等的时候,它们才相等。注意:比较的时候注意“==”和“===”,双等号(==)在做比较的时候,做了类型转换,而全等号(===)是值和类型的比较,只有值和类型同时相等时,才能相等。
varstudent1='{}';
varstudent2='{}';
console.log(student1===student2);//true
两个相同字符串的比较,是值(‘{}')的比较,完全相等。
JavaScript中的引用类型的比较是引用地址的比较:
varstudent1={};
varstudent2={};
console.log(student1===student2);//false
可见,两个空对象并不相等。
疑问:为什么两个一模一样的对象不相等呢?
扩展:因为引用类型是按引用地址访问的,引用类型的比较其实就是比较两个对象在堆内存中的地址是否相同,那么,很明显,student1和student2在堆内存中地址是不同的,所以,即使看到一模一样的两个对象,也不一定相等。
2.5区别五
JavaScript中的值类型的变量赋值过程中,在从一个变量到另一个变量赋值基本类型(值类型)时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:
varstr1="abcdef";
varstr2=str1;
str1='abc';
console.log(str1);//abc
console.log(str2);//abcdef
从上述代码示例中可以看出,str1中保存的值为 abcdef ,当使用 str1 来初始化 str2 时,str2 中保存的值也为abcdef,但str2中的值和str1中的值是完全独立的,str2的值只是str1中的值的一个副本,接下来,这两个变量可以参加任何操作而相互不影响。其实就是说,基本类型的变量在赋值操作后,两个变量是相互独立的,都不受影响的。
JavaScript中的引用类型的变量赋值过程中,在从一个变量到另一个变量赋值引用类型时,同样也会在该变量上创建一个新“值”,然后再把该“值”复制到为新变量分配的位置上。不同的是,复制的不是真正的“值”,而是真正的值在堆区中的存放地址:
varstudent1=;
varstudent2=student1;
student2.age=100;
console.log(student1.age);//100
console.log(student2.age);//100
console.log(student1===student2);//true
引用类型的赋值其实是对象保存在栈区地址指针的赋值,两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响。
领取专属 10元无门槛券
私享最新 技术干货