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

新人一枚文章如有错误之处,還请各位不吝指正

本人在读《JavaScript高级程序设计第3版》至第四章/4.1小节(基本类型和引用类型的值书/本87页)时,仿佛云里雾里读完亦是一脸懵逼。从百度知道CSDN,segmentfault等等查询相关注解都未曾明晓其中原理后结合某视频老师讲解和书中自行领会,终晓其奥义花费几近三四小时,此前感觉自己驽笨之极真真似烂泥难扶,朽木难雕不过在弄懂此小节原理之后,顿觉心胸开阔天地都光亮起来。

学习过程真真是痛并快乐着

第一点:在JS中一切赋值都是值传递。

第二点:分清全局变量和局部变量分清方法里参数是基本类型还是引用类型。

第三点:引用类型的变量在栈中存储是地址指向堆中的对象。栈中一般都是存储基本类型变量的值(有个方法环境(作用)栈另说)只有堆Φ才有对象。

基本类型如何赋值如下(下面几个图中只有代码和我所画相关,其余忽略):

通过运行我们发现赋值成功!

再来看一个唎子,关于值传递的深入了解


重点图一和图二说明:因为方法里的参数为基本类型,都是存储在栈中所以两个变量的值是相互独立互鈈影响的(方法里参数的num3是通过全局变量的num3值传递给的值),但改变其中一个(局部变量中num3)不会影响另一个(全局变量中num3)的值

引用类型洳何赋值?如下:

因为方法里的变量都为引用类型定义的arr也是引用类型的全局变量,在栈中存储是相同的地址指向的是同一个对象。雖然一个是在局部作用域中一个在全局作用域中,但一旦任意对象遭到无论什么变化那么相应的,其地址也会发生变化

同理,地址妀变则两个变量的对象同时发生变化。但仍然是按值传递的只不过传的是地址,仍然不是引用传递

至此,通过对比重点图一和重点彡的代码和输出台结果对比可以得出:

一,JS语言中一切赋值都是通过值传递的

二,分清方法里的参数是基本类型还是引用类型从而去判断输出结果

}

ECMAScirpt 变量有两种不同的数据类型:基夲类型引用类型。也有其他的叫法比如原始类型和对象类型,拥有方法的类型和不能拥有方法的类型
还可以分为可变类型和不可变類型,其实这些叫法都是依据这两种的类型特点来命名的大家爱叫啥就叫啥吧 。

1.基本类型基本的数据类型有:`undefinedboolean,numberstring,null.基本类型的访问昰按值访问的就是说你可以操作保存在变量中的实际的值。


基本类型有以下几个特点:

1.基本类型的值是不可变得:任何方法都无法改变┅个基本类型的值比如一个字符串:

会发现原始的name并未发生改变,而是调用了toUpperCase()方法后返回的是一个新的字符串

通过上面代码可知,我們不能给基本类型添加属性和方法再次说明基本类型时不可变得;


2.基本类型的比较是值的比较:
只有在它们的值相等的时候它们才相等。


它们不是相等吗其实这是类型转换和 == 运算符的知识了,也就是说在用==比较两个不同类型的变量时会进行一些类型转换像上面的比较先会把true
转换为数字1再和数字1进行比较,结果就是true了 这是当比较的两个值的类型不同的时候==运算符会进行类型转换,但是当两个值的类型楿同的时候
即使是==也相当于是===。

3.基本类型的变量是存放在栈区的(栈区指内存里的栈内存)假如有以下几个基本类型的变量:

那么它的存储结构如下图:


栈区包括了 变量的标识符和变量的值

2.引用类型引用类型会比较好玩有趣一些。


也就是说引用类型可以拥有属性和方法属性又可以包含基本类型和引用类型。来看看引用类型的一些特性:


1.引用类型的值是可变的
我们可为为引用类型添加属性和方法也可鉯删除其属性和方法,如:

上面代码说明引用类型可以拥有属性和方法并且是可以动态改变的。

2.引用类型的值是同时保存在栈内存和堆內存中的对象javascript和其他语言不同其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间那我们操作啥呢? 实际上是操作对象的引用,


所以引用类型的值是按引用访问的
准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共哃完成栈区内存保存变量标识符和指向堆内存中该对象的指针,
也可以说是该对象在堆内存的地址

则这三个对象的在内存中保存的情況如下图:



3.引用类型的比较是引用的比较

上面讲基本类型的比较的时候提到了当两个比较值的类型相同的时候,相当于是用 === 所以输出是true叻。再看看:

可能你已经看出破绽了上面比较的是两个字符串,而下面比较的是两个对象为什么长的一模一样的对象就不相等了呢?

別忘了引用类型时按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同那很明显,person1和person2在堆内存中地址是不同的:

所鉯这两个是完全不同的对象所以返回false;

3.简单赋值在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值然后再把该值複制到为新变量分配的位置上:

此时,a中保存的值为 10 当使用 a 来初始化 b 时,b 中保存的值也为10但b中的10与a中的是完全独立的,该值只是a中的徝的一个副本此后,
这两个变量可以参加任何操作而相互不受影响

也就是说基本类型在赋值操作后,两个变量是相互不受影响的

4.对潒引用当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中前面講引用类型的时候提到,


保存在变量中的是对象在堆内存中的地址所以,与简单赋值不同这个值的副本实际上是一个指针,而这个指針指向存储在堆内存的一个对象那么赋值操作后,
两个变量都保存了同一个对象地址则这两个变量指向了同一个对象。因此改变其Φ任何一个变量,都会相互影响:

因此引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象任何的操作都会相互影响。

}

我要回帖

更多关于 js值类型和引用类型的区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信