时间:2021-05-26
我的一句话总结:原始值不管是变量赋值还是函数传递都不会改变原值,引用值不管是变量赋值还是函数传递,如果新变量重新赋值,则不会影响原引用值,如新变量是直接操作,就会影响原引用值。
首先明确,值和类型是两个不同的概念。例如,null是null类型的唯一值、undefined是undefined类型的唯一值、而true和false是boolean类型仅有的两个值等。在任何语言中,值的操作都可以归纳为以下3个方面。
复制值:即把值赋值给新变量,或者通过变量把值赋值给另一个变量、属性或数组元素。
传递值:即把值作为参数传递给函数或方法。
比较值:即把值与另一个值进行比较,看是否相等。
由于值类型数据和引用型数据的值存在形式不同,自然操作它们的方法和所产生的结果也是不同的。注意,当值为值类型数据时,我们常称之为原始值或基本值;当值为引用型数据时,我们常称之为引用值或复合值。
1.使用原始值
对于原始值来说,其操作的3个层面说明如下。
1)复制值
在赋值语句中,操作的过程将会产生一个实际值的副本,副本的值和实际值之间没有任何联系,它们独自位于不同的栈区或者堆区。这个副本可以存储变量、对象的属性和数组的元素。例如:
在上面示例中,分别把值123复制3份给变量a、数组b和对象c,虽然它们的值是相等的,但是它们之间是相互独立的。
2)传递值
当把值传递给函数或方法时,传递的值仅是副本,而不是值本身。例如,如果在函数中修改传递进来的值时,结果只能够影响这个参数值的副本,并不会影响到原来的值。
var a = 123; // 原来的值 function f(x){ x = x + x; } f(a); // 调用函数修改传递的值 alert(a); // 查看变量a的值是否受影响,返回值为123,说明没有变化3)比较值
在上面的示例中我们也可以看到,当对原始值进行比较时,进行逐字节的比较来判断它们是否相等。比较的是值本身,而不是值所处的位置,固然比较的结果可能会相等,但只是说明它们所包含的字节信息是相同的。
2.使用引用值
对于引用值来说,其操作的3个层面说明如下。
1)复制值
在赋值语句中,所赋的值是对原值的引用,而不是原值副本,更不是原值本身。也就是说,进行赋值之后,变量保存的都是对原值的引用(即原值的存储地址)。当在多个变量、数组元素或对象属性中间复制时,它们都会与原始变量保存的引用相同。
所有引用具有相同的效力和功能,都可以执行操作,如果通过其中的一个引用编辑数据,这种修改将会在原值及其他相关引用中体现出来。例如:
但是,如果给变量b重新赋予新值,则新值不会影响原值内容。例如:
var a = [1,2,3]; // 赋值数组引用 b = a; // 复制值 b = 4; // 为变量b重写赋值 alert(a[0]); // 变量a的内容保持不变重复赋值实际上是覆盖变量对原值的引用,变为另一个值的副本或对其引用。所以不会对原值产生影响,演示示意图如图4-2所示。
2)传递值
当使用引用将数据传递给函数时,传递给函数的也是对原值的一个引用,函数可以使用这个引用来修改原值本身,任何修改在函数外部都是可见的。例如:
var a = [1,2,3]; function f(x){ x[0] = 4; // 在函数中修改参数值 } f(a); // 传递引用值 alert(a[0]); // 返回4,原值发生变化请注意,在函数内修改的是对外部对象或数组的引用,而不是对象或数组本身的值。在函数内可以使用引用来修改对象的属性或数组的元素,但是如果在函数内部使用一个新的引用覆盖原来的引用,那么在函数内部的修改就不会影响原引用的值,函数外部也是看不到的。
var a = [1,2,3]; function f(x){ x = 4; // 在函数中修改参数值 } f(a); // 传递引用值 alert(a[0]); // 返回1,原值不会发生变化3)比较值
当比较两个引用值时,比较的是两个引用地址,看它们引用的原值是否为同一个副本,而不是比较它们的原值字节是否相等。当对两个不同值进行引用时,尽管它们具有相同的字节构成,但是这两个引用的值却是不相等的。
var a = new Number(1); // 引用值a var b = new Number(1); // 引用值b var c = a; // 把a的引用赋值给c alert(a==b); // 返回false alert(a==c); // 返回true所以,{} == {},[] == [],都返回false。因为引用地址不同。
总之,对于任何语言来说,使用值和使用引用都是数据操作的两种基本方法。当我们操作数据时,要采用什么方法来进行处理,主要看数据的类型。值类型和引用型数据参与运算的方式不同,值类型数据通过使用值来操作数据,而引用型数据使用引用来操作数据。运算方式的不同,自然所产生的结果也不同。我们不妨再看一个示例:
var s = "abc"; // 字符串,值类型数据 var o = new String(s); // 字符串对象,被装箱后的字符串 function f(v){ // 运算函数 v.toString = function(){ // 修改参数的方法toString() return 123; }; } f(s); // 传入值 alert(s); // 返回字符串"abc",说明运算没有对原数据造成影响 f(o); // 传入引用 alert(o); // 返回数值123,说明运算已经影响到原数据的内部结构值类型是以实际值参与运算的,因此与原数据没有直接联系。而引用型以引用地址参与运算,计算的结果会影响到引用地址所关联的堆区数据块。但是,有一点例外,对于JavaScript的字符串来说,它的操作方法就比较复杂,详情请google!
以上这篇JavaScript数据操作_浅谈原始值和引用值的操作本质就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了javascript内存分配原理。分享给大家供大家参考,具体如下:JavaScript中的变量分为两种,原始值和引用值。原始值指的是原始数据类型的
原始值和引用值在ECMAScript中,变量可以存放两种类型的值,即原始值和引用值。原始值指的就是代表原始数据类型(基本数据类型)的值,即Undefined,N
一、变量在javascript变量中可以存放两种类型的值:原始值和引用值。原始值存储在栈上的简单字段,也就是值直接存储在变量所标示的位置内。引用值存储在堆内的对
本文实例讲述了javascript原始值和对象引用的方法。分享给大家供大家参考。具体分析如下:一句话来说:原始值是不可变的,而对象引用是可变的。js中的原始值(
在ECMAscript中,变量可以存放两种类型的值,即原始值和引用值原始值指的是代表原始数据类型的值,也叫基本数据类型,包括:Number、Stirng、Boo