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的递增/递减运算符和带操作的赋值运算符的等价式
Dec 08 Javascript
一个很简单的jquery+xml+ajax的无刷新树结构(无css,后台是c#)
Jun 02 Javascript
Jquery和JS获取ul中li标签的实现方法
Jun 02 Javascript
jQuery插件imgAreaSelect基础讲解
May 26 jQuery
vue-router history模式下的微信分享小结
Jul 05 Javascript
Vue实现按钮旋转和移动位置的实例代码
Aug 09 Javascript
基于Vue-Cli 打包自动生成/抽离相关配置文件的实现方法
Dec 09 Javascript
小程序实现订单倒计时功能
Apr 23 Javascript
解决vue单页面应用中动态修改title问题
Jun 09 Javascript
layui数据表格实现重载数据表格功能(搜索功能)
Jul 27 Javascript
vue实现文件上传读取及下载功能
Nov 17 Javascript
JavaScript进阶(二)词法作用域与作用域链实例分析
May 09 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/11/25 PHP
php与java通过socket通信的实现代码
2013/10/21 PHP
php制作圆形用户头像的实例_自定义封装类源代码
2017/09/18 PHP
PHP使用Redis实现防止大并发下二次写入的方法
2017/10/09 PHP
yii框架redis结合php实现秒杀效果(实例代码)
2017/10/26 PHP
php-fpm中max_children的配置
2019/03/15 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
2019/10/02 PHP
可以支持多中格式的JS键盘
2007/05/02 Javascript
javascript 操作文件 实现方法小结
2009/07/02 Javascript
JavaScript实现快速排序(自已编写)
2012/12/19 Javascript
js判断undefined类型,undefined,null, 的区别详细解析
2013/12/16 Javascript
jquery数组封装使用方法分享(jquery数组遍历)
2014/03/25 Javascript
seaJs的模块定义和模块加载浅析
2014/06/06 Javascript
jQuery中innerWidth()方法用法实例
2015/01/19 Javascript
百度搜索框智能提示案例jsonp
2016/11/28 Javascript
node.JS md5加密中文与php结果不一致的解决方法
2017/05/05 Javascript
如何抽象一个Vue公共组件
2017/10/17 Javascript
JS声明对象时属性名加引号与不加引号的问题及解决方法
2018/02/16 Javascript
微信小程序通过保存图片分享到朋友圈功能
2018/05/24 Javascript
jQuery实现基本隐藏与显示效果的方法详解
2018/09/05 jQuery
JQuery Ajax执行跨域请求数据的解决方案
2018/12/10 jQuery
JavaScript事件对象深入详解
2018/12/30 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
javascript开发实现贪吃蛇游戏
2020/07/31 Javascript
Javascript中window.name属性详解
2020/11/19 Javascript
centos系统升级python 2.7.3
2014/07/03 Python
Python 实现两个列表里元素对应相乘的方法
2018/11/14 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
2019/06/17 Python
Pycharm Plugins加载失败问题解决方案
2020/11/28 Python
Grid 宫格常用布局的实现
2020/01/10 HTML / CSS
职位说明书范文
2014/05/07 职场文书
小学绿色学校申报材料
2014/08/23 职场文书
武当山导游词
2015/02/03 职场文书
信仰纪录片观后感
2015/06/08 职场文书
详解Oracle数据库中自带的所有表结构(sql代码)
2021/11/20 Oracle
《艾尔登法环》发布最新「战技」宣传片
2022/04/03 其他游戏