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 相关文章推荐
jquery提示 "object expected"的解决方法
Dec 13 Javascript
js判断60秒以及倒计时示例代码
Jan 24 Javascript
Javscript删除数组中指定元素并返回新数组
Mar 06 Javascript
jQuery+CSS3折叠卡片式下拉列表框实现效果
Nov 02 Javascript
原生JS实现平滑回到顶部组件
Mar 16 Javascript
微信小程序 本地存储及登录页面处理实例详解
Jan 11 Javascript
javascript数据结构中栈的应用之符号平衡问题
Apr 11 Javascript
jQuery Layer弹出层传值到父页面的实现代码
Aug 17 jQuery
JS二分查找算法详解
Nov 01 Javascript
Vue.js实现列表清单的操作方法
Nov 15 Javascript
ant-design-vue 快速避坑指南(推荐)
Jan 21 Javascript
js轮播图之旋转木马效果
Oct 13 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
Zend的Registry机制的使用说明
2013/05/02 PHP
php查看当前Session的ID实例
2015/03/16 PHP
Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解
2016/11/10 PHP
PHP 中 var_export、print_r、var_dump 调试中的区别
2018/06/19 PHP
PHP安装memcache扩展的步骤讲解
2019/02/14 PHP
浅谈PHP中的Trait使用方法
2019/03/22 PHP
PHP使用POP3读取邮箱接收邮件的示例代码
2020/07/08 PHP
在html页面中包含共享页面的方法
2008/10/24 Javascript
解决表单中第一个非隐藏的元素获得焦点的一个方案
2009/10/26 Javascript
多种方法实现360浏览器下禁止自动填写用户名密码
2014/06/16 Javascript
javascript 控制input只允许输入的各种指定内容
2014/06/19 Javascript
JS动态添加Table的TR,TD实现方法
2015/01/28 Javascript
jQuery实现带延迟效果的滑动菜单代码
2015/09/02 Javascript
最简单的tab切换实例代码
2016/05/13 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
2016/09/01 Javascript
二维码图片生成器QRCode.js简单介绍
2017/08/18 Javascript
React 使用browserHistory项目访问404问题解决
2018/06/01 Javascript
JS数组方法slice()用法实例分析
2020/01/18 Javascript
[01:33]完美世界DOTA2联赛PWL S3 集锦第二期
2020/12/21 DOTA
Python使用修饰器进行异常日志记录操作示例
2019/03/19 Python
Python实现将HTML转成PDF的方法分析
2019/05/04 Python
Python+OpenCv制作证件图片生成器的操作方法
2019/08/21 Python
django框架auth模块用法实例详解
2019/12/10 Python
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
2010/07/20 HTML / CSS
Sephora丝芙兰澳洲官方网站:国际知名化妆品购物
2016/10/27 全球购物
TUMI新加坡官网:国际领先的商旅箱包品牌
2019/01/12 全球购物
为您的家、后院、车库等在线购物:Spreetail
2019/06/17 全球购物
美赞臣营养马来西亚旗舰店:Enfagrow马来西亚
2019/07/26 全球购物
印度领先的眼镜电子商务网站:Lenskart
2019/12/16 全球购物
Haggar官网:美国男装品牌
2020/02/16 全球购物
为什么要有struct关键字
2012/05/08 面试题
优秀应届毕业生自荐信
2013/11/16 职场文书
小学教师师德反思
2014/02/03 职场文书
律师函格式范本
2015/05/27 职场文书
辞职信怎么写?
2019/05/21 职场文书
iSCSI服务器CHAP双向认证配置
2022/04/01 Servers