JavaScript中值类型和引用类型的区别


Posted in Javascript onFebruary 23, 2017

JavaScript的数据类型分为两类:原始类型和对象类型。其中,原始类型包括:数字、字符串和布尔值。此外,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中值类型和引用类型的区别

所以,可以看出,即使两个对象完全一样,但是在堆区中的存放地址是不一样的,所以在比较时,是不相等的。

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中值类型和引用类型的区别

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 相关文章推荐
JS定时关闭窗口的实例
May 22 Javascript
Array栈方法和队列方法的特点说明
Jan 24 Javascript
javascript中解析四则运算表达式的算法和示例
Aug 11 Javascript
JS简单去除数组中重复项的方法
Sep 13 Javascript
简单理解vue中el、template、replace元素
Oct 27 Javascript
原生js实现旋转木马轮播图效果
Feb 27 Javascript
node+express+ejs使用模版引擎做的一个示例demo
Sep 18 Javascript
Angular中使用MathJax遇到的一些问题
Dec 15 Javascript
GOJS+VUE实现流程图效果
Dec 01 Javascript
Vue开发环境中修改端口号的实现方法
Aug 15 Javascript
javascript实现前端成语点击验证
Jun 24 Javascript
浅谈vue单页面中有多个echarts图表时的公用代码写法
Jul 19 Javascript
canvas绘制环形进度条
Feb 23 #Javascript
微信小程序 两种为对象属性赋值的方式详解
Feb 23 #Javascript
js实现文字跑马灯效果
Feb 23 #Javascript
微信小程序 出现错误:{"baseresponse":{"errcode":-80002,"errmsg":""}}解决办法
Feb 23 #Javascript
JS正则表达式验证密码格式的集中情况总结
Feb 23 #Javascript
js模拟微博发布消息
Feb 23 #Javascript
Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信
Feb 23 #Javascript
You might like
开发大型 PHP 项目的方法
2007/01/02 PHP
SMARTY学习手记
2007/01/04 PHP
php 5.3.5安装memcache注意事项小结
2011/04/12 PHP
php实现二叉树中和为某一值的路径方法
2018/10/14 PHP
jquery load事件(callback/data)使用方法及注意事项
2013/02/06 Javascript
js将json格式内容转换成对象的方法
2013/11/01 Javascript
express的中间件cookieParser详解
2014/12/04 Javascript
jQuery源码解读之removeClass()方法分析
2015/02/20 Javascript
javascirpt实现2个iframe之间传值的方法
2016/06/30 Javascript
全面介绍javascript实用技巧及单竖杠
2016/07/18 Javascript
angularjs的select使用及默认选中设置
2017/04/08 Javascript
node koa2实现上传图片并且同步上传到七牛云存储
2017/07/31 Javascript
Vue中this.$router.push参数获取方法
2018/02/27 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
2018/08/20 Javascript
微信小程序 搜索框组件代码实例
2019/09/06 Javascript
如何使用JS console.log()技巧提高工作效率
2020/10/14 Javascript
vue form表单post请求结合Servlet实现文件上传功能
2021/01/22 Vue.js
[59:15]EG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/29 DOTA
centos系统升级python 2.7.3
2014/07/03 Python
使用Python爬了4400条淘宝商品数据,竟发现了这些“潜规则”
2018/03/23 Python
Python基于TCP实现会聊天的小机器人功能示例
2018/04/09 Python
Python将8位的图片转为24位的图片实现方法
2018/10/24 Python
python如何爬取网站数据并进行数据可视化
2019/07/08 Python
tensorflow实现对张量数据的切片操作方式
2020/01/19 Python
解决TensorFlow训练内存不断增长,进程被杀死问题
2020/02/05 Python
Python打印特殊符号及对应编码解析
2020/05/07 Python
Django权限设置及验证方式
2020/05/13 Python
对Keras中predict()方法和predict_classes()方法的区别说明
2020/06/09 Python
pytorch __init__、forward与__call__的用法小结
2021/02/27 Python
CSS3实现文本垂直排列的方法
2018/07/10 HTML / CSS
欧缇丽英国官方网站:Caudalie英国
2016/08/17 全球购物
香港彩色隐形眼镜在线商店:Stunninglens(全球免费送货)
2019/05/10 全球购物
AURALog面试题软件测试方面
2013/10/22 面试题
2016年万圣节活动个人总结
2016/04/05 职场文书
2019升学宴主持词范本5篇
2019/10/09 职场文书
SQL Server表分区降低运维和维护成本
2022/04/08 SQL Server