JavaScript中值类型和引用类型的区别
JavaScript的数据类型分为两类:原始类型和对象类型。其中,原始类型包括:数字、字符串和布尔值。此外,JavaScript中还有两个特殊的原始值:null和undefined,它们既不是数字也不是字符串,更不是布尔值。它们通常分别代表了各自特殊类型的唯一成员(详情可点击查看:JavaScript中的null和undefined)。JavaScript中除了数字、字符串、布尔值、null和undefined之外的就是对象了。
JavaScript中值类型和引用类型的区别
JavaScript中的值类型的值是不可变的:
任何方法都无法改变值类型的值。数字、布尔值、null和undefined等都属于不可变类型。比如,修改一个数值的内容,本身就说不通。虽然字符串可以被看成是由字符组成的数组,可能会被认为是可变的。但是,在JavaScript中,字符串是不可变的。在实际操作过程中,可以访问字符串任意位置的文本,单JavaScript并未提供修改已知字符串的文本内容的方法。
代码:
var str = 'abcdef';
console.log(str.toUpperCase()); // ABCDEF
console.log(str); // abcdef
可见,原始的str字符串值并未发生改变,仍然是小写的abcdef,第二行代码,只是调用了字符串的toUpperCase()方法后,返回的是一个新的字符串。
JavaScript中的引用类型的值是可变的:
代码:
var student = {name: '张三', age: 26};
console.log(student.name); // 张三
student.name = '李四';
console.log(student.name); // 李四
疑问:如果像studen.name = '李四'这段代码一样,给str也做相同的操作,str的值不也是改变了吗?
扩展:如果给str重新赋值,那么改变的是变量的值,给str重新赋值了,并没有改变字符串内容,改变的只是变量str的内容
JavaScript中的值类型无法添加属性和方法:
代码:
var student = '张三';
student.age = 26;
student.run = function () {
console.log('跑步中...');
}
console.log(student.age); // undefined
console.log(student.run); // undefined
通过代码示例,可知,不能给值类型添加属性和方法。从而,也更加说明了值类型是不可变的。
JavaScript中的引用类型可以添加属性和方法:
代码:
var student = {};
student.age = 26;
student.run = function () {
console.log('跑步中...');
}
console.log(student.age); // 26
console.log(student.run);
/*
function () {
console.log('跑步中...');
}
*/
JavaScript中的值类型的变量是存放在栈区的:
JavaScript中的值类型的变量存储结构如下表模拟所示,栈区中包括了变量的标识符以及变量所对应的值。

JavaScript中的引用类型的变量也是存放在栈区的,不同的是,引用类型在栈区中存放的是变量标识符以及变量所对应值得引用地址,而变量所对应的值被存放在堆区中:

所以,可以看出,即使两个对象完全一样,但是在堆区中的存放地址是不一样的,所以在比较时,是不相等的。
JavaScript中的值类型的比较是值的比较:
JavaScript中的值类型在进行比较的时候,只有在它们的值相等的时候,它们才相等。注意:比较的时候注意“==”和“===”,双等号(==)在做比较的时候,做了类型转换,而全等号(===)是值和类型的比较,只有值和类型同时相等时,才能相等。
代码:
var student1 = '{}';
var student2 = '{}';
console.log(student1 === student2); // true
两个相同字符串的比较,是值(‘{}’)的比较,完全相等。
JavaScript中的引用类型的比较是引用地址的比较:
代码:
var student1 = {};
var student2 = {};
console.log(student1 === student2); // false
可见,两个空对象并不相等。
疑问:为什么两个一模一样的对象不相等呢?
扩展:因为引用类型是按引用地址访问的,引用类型的比较其实就是比较两个对象在堆内存中的地址是否相同,那么,很明显,student1和student2在堆内存中地址是不同的,所以,即使看到一模一样的两个对象,也不一定相等。
JavaScript中的值的变量赋值,是值得复制:
JavaScript中的值类型的变量赋值过程中,在从一个变量到另一个变量赋值基本类型(值类型)时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:
代码:
var str1 = 'abcdef'; var str2 = str1; str1 = 'abc'; console.log(str1); // abc console.log(str2); // abcdef
从上述代码示例中可以看出,str1中保存的值为 abcdef ,当使用 str1 来初始化 str2 时,str2 中保存的值也为abcdef,但str2中的值和str1中的值是完全独立的,str2的值只是str1中的值的一个副本,接下来,这两个变量可以参加任何操作而相互不影响。其实就是说,基本类型的变量在赋值操作后,两个变量是相互独立的,都不受影响的。

JavaScript中的引用类型的变量赋值过程中,在从一个变量到另一个变量赋值引用类型时,同样也会在该变量上创建一个新“值”,然后再把该“值”复制到为新变量分配的位置上。不同的是,复制的不是真正的“值”,而是真正的值在堆区中的存放地址:
代码:
var student1 = {age: 26};
var student2 = student1;
student2.age = 100;
console.log(student1.age); // 100
console.log(student2.age); // 100
console.log(student2 === student1); // true
引用类型的赋值其实是对象保存在栈区地址指针的赋值,两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响。

JavaScript中值类型和引用类型的区别的更多相关文章
- JavaScript中值类型与引用类型
JavaScript中的变量类型有哪些? 值类型:字符串(string).数值(number).布尔值(boolean).null.undefined 引用类型:对象(Object).数组(Array ...
- java中值类型和引用类型的区别
[定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法是传入的变量的值也将改变. 值类型表示复制一个当前变量传给方法,当你 ...
- c#中值类型和引用类型的区别
1. 值类型的数据存储在内存的栈中:引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址. 2. 值类型存取速度快,引用类型存取速度慢. 3. 值类型表示实际数据,引 ...
- js中的值类型和引用类型的区别
1.JavaScript中的变量类型有哪些? (1)值类型(基本类型):字符串(String).数值(Number).布尔值(Boolean).Undefined.Null (这5种基本数据类型是按 ...
- C#中关于值类型和引用类型的区别
小声哔哔 一直以来对于值类型与引用类型之间的区别都不是特别清晰,直到踩了坑.... 正好最新闲暇,便想着梳理梳理这一两年来遇到的奇葩问题和解决方案,顺便就把它给拎出来记一下,免得以后再摔跤 值类型与引 ...
- JAVA初学(1):值类型和引用类型的区别
JAVA值类型和引用类型的区别(转) [定义] 引用类型表示你操作的数据是同一个,也就 ...
- C#类和接口、虚方法和抽象方法及值类型和引用类型的区别
1.C#类和接口的区别接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念!而类是负责功能的具体实现!在类中也有抽象类的定义,抽象类与接口的区别在于:抽象类是一个不完全的类,类里面有抽 ...
- C#入门篇6-7:字符串操作 看看字符串的特殊之处 值类型与引用类型的区别
//看看字符串的特殊之处值类型与引用类型的区别 public static void CompareString(string stra, string strb, int i) { #region ...
- C# 值类型和引用类型的区别
C# 值类型和引用类型的区别 1. 值类型的数据存储在内存的栈中:引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址. 2. 值类型存取速度快,引用类型存取速度慢. 3. 值类型表示实 ...
随机推荐
- REST API设计规范
完全面向资源,API以复数形式表示 路径(Endpoint) http://example.com/libraries //列出所有图书馆 http://example.com/books //列出所 ...
- C# 调用外部dll(转)
C# 调用外部dll 一. DLL与应用程序 动态链接库(也称为DLL,即为"Dynamic Link Library"的缩写)是Microsoft Windows最 ...
- 【Xilinx-Petalinux学习】-02-建立PetaLinux工程
前面我已经把PetaLinux成功安装到了Ubuntu虚拟机当中了,接下来就要实际操作,将PetaLinux移植到我们自己的硬件平台当中去. step1:硬件描述文件 有两种PetaLinux工程建立 ...
- python with用法
python中with可以明显改进代码友好度,比如: with open('a.txt') as f: print f.readlines() 为了我们自己的类也可以使用with, 只要给这个类增加两 ...
- Android与Linux以及GNU的关系
转帖自 http://www.eefocus.com/Kevin/blog/09-11/179409_1dc9a.html 作者: Kevin 本文转贴自 http://mmdays.com/2008 ...
- iOS 准备
iOS 编程知识点 iOS 基础知识点 iOS 之 系统机制 Xcode 使用技巧 Mac 使用技巧 iOS 之 英语 iOS 之 编外知识点 iOS 知识库链接
- Spring学习笔记IOC与AOP实例
Spring框架核心由两部分组成: 第一部分是反向控制(IOC),也叫依赖注入(DI); 控制反转(依赖注入)的主要内容是指:只描述程序中对象的被创建方式但不显示的创建对象.在以XML语言描述的配置文 ...
- js原生之一个面向对象的应用
function IElectricalEquipment() { } IElectricalEquipment.prototype = { poweron: fu ...
- SQL 查询同一天日期内的数据
条件如下: convert(date,a.dtClock) = convert(date,b.dtClock)
- 如何在Visio 2007中画接口和实现类的关系图
http://blog.sina.com.cn/s/blog_53fc9db50100as5o.html 在Visio图形元素上,点击右键,选择“形状显示选项”,将“实现链接”选中,这个时候,类图形元 ...