变量——基本类型和引用类型的值

基本类型和引用类型的值

一、综述

  ECMAScript变量可能包含两种不同的数据类型的值:基本类型值和引用类型值。

  基本类型值是指简单的数据段,而引用类型值指那些可能由多个值构成的对象。

  在给一个变量赋值时,解析器必须确定这个值是基本类型值还是引用类型值。

  5种基本数据类型(Undefined、Null、Boolean、Number、String)是按值访问的,因此可以操作保存在变量中实际的值。

  引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript不允许直接访问内存中的位置也就是说不能直接操作对象的内存空间。

  在操作对象时,实际上在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问的。(这种说法不严密,当复制保存着对象的某个变量时,操作的是对象的引用。但在为对象添加属性时,操作的是实际的对象)。

  注:在很多语言中,字符串以对象形式来表示,因此被认为是引用类型的。ECMAScript放弃了这一传统。

二、动态的属性

 

  定义基本类型值和引用类型值的方式是类似的:创建一个变量并为该变量赋值。但是,当这个值存到变量中以后,对不同类型值可以执行的操作则大相径庭。对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。例如:

  var person = new Object();

  person.name = "Nicholas";

  alert(person.name);  //"Nicholas"

  在上例中,我们创建了一个对象并将其保存在了person变量中。然后,我们为该对象添加了一个名为name的属性,并将字符串值“Nicholas”赋给了这个属性。紧接着,通过alert()访问了这个属性。如果对象不被销毁或者这个属性不被删除,则这一属性将一直存在。

  但是,我们不能为基本类型的值添加属性,尽管这样做不会导致任何错误。比如:

  var name = "Nicholas";

  name.age = 27;

  alert(name.age);  //undefined

  

  在这个例子中。我们为字符串name定义了一个名为age的属性,并为该属性赋值27。但在下一行访问这个属性时,发现改属性不见了。这说明只能给引用类型值动态地添加属性,以便将来使用。

 

三、复制变量值


  除了保存的方式不同之外,在从一个变量向另一个变量复制基本类型值和引用类型值时,也存在不同。如果一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到新变量分配的位置。来看一个例子:

  var num1 = 5;

  var num2 = num1;

  在此,num1中保存的值是5。当使用num1的值来初始化num2时,num2中也保存了值5.但num2中的5与num1中的5是完全独立的,该值只是num1中5的一个副本。此后,这两个变量可以参与任何操作而不相互影响。

  复制前变量对象

   
   
num1
5

(Number类型)

复制后变量对象

   
num2
5

(Number类型)

num1
5

(Number类型)

  ·当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制给一个新变量分配的空间中。不同的时,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,两个变量实际上将引用同一个对象。因此,改变其中一个变量,就会影响另一个变量。如下例所示:

  var obj1 = new Object();

  var obj2 = obj1;

  obj1.name = "NIcholas";

  alert(obj2.name);  //"NIcholas"

  首先,变量Obj1保存了一个对象的新实例。然后,这个值被复制到了obj2中;换句话说,obj1和obj2都指向同一个对象。这样,当为obj1添加name属性后,可以通过obj2来访问这个属性。因为两个变量引用的都是同一个对象。下图展示了保存在变量对象中的变量和保存在堆中的对象之间的这种关系;

四、传递参数

  ECMAScript中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而引用类型变量的复制一样。有不少开发人员在这一点上可能会感到困惑,因此为访问变量有按值和按引用两种方式,而参数只能按值传递。

  向参数传递基本变量的值时,被传递的值会被复制给一个局部变量。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数外部。请看下面这个例子:

  function addTen(num){

    num+=10;

    return num;

  }  

  var count = 20;

  var result = addTen(count);

  alert(count);  //20,无变化

  alert(result);   //30

  

  这里的函数addTen()有一个参数num,而参数实际上是函数的局部变量。在调用这个函数时,变量count作为参数被传递给函数,这个变量的值是20.于是,数值20被复制给参数num以便在addTen()中使用。在函数内部,参数num的值被加上了10,但这一变化不会影响函数外部的count变量。参数num与变量count互不相识,他们仅仅是相同的值。假如num是按引用传递的话,那么变量count的值也将便成为30,从而反应函数内部的修改。当然,使用等值基本类型值来说明按值传递参数比较简单,但如果使用对象,那问题就不怎么好理解了。再举一个例子:

  function setName( obj ){

    obj.name = "Nicholas";

  }

  var person = new Object() ;

  setName( person );

  alert(person.name);   //"Nicholas"

  以上代码中创建一个对象,并将其保存在了变量person中。然后,这个变量被传递到setName()函数之中就被复制给了obj。在这个函数内部,obj和person引用的是同一个对象。换句话说,即使这个变量是按值传递的,obj也会按引用来访问一个对象。于是,当在函数内部为obj添加name属性后,函数外部的person也将有所反映;因为person指向在内存中只有一个,而且是全局对象。很多开发人员错误地认为:在局部作用域中修改对象会在全局作用域中反映出来,就说明参数是按引用传递的。为了证明对象是按值传递的,我们再看下例:

  function setName(obj){

    obj.name = "Nicholas";  

    obj = new Object();

    obj.name = "Greg";

  }

  var person = new Object();

  setName( person );

  alert( person.name );  //"Nicholas"

这个例子与前一个例子的唯一区别,就是在setName()函数中添了两行代码:一行代码为obj重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的name属性。在吧person传递给setName()后,其name属性被设置为“Nicholas”。然后,又将一个新对象赋给变量obj,同时将其name属性设置为“Greg”。如果person是按引用传递的,那么person就会被自动修改为指向其name属性值为“Greg”的新对象。但是,当接下来再访问person.name时,显示的值仍然是“Nicholas”。这说明即使在函数内部修改了参数的值,但原始的引用仍然保持不变。实际上,当在函数内部重写obj时,这个变量引用就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。

  注:可以把ECMAScript函数参数先锋乡城局部变量

五、检测类型

  要检测一个变量是不是基本数据类型,typeof操作符是最佳工具,即typeof操作符是确定一个变量是字符串、数值、布尔,还是undefined的最佳工具、如果变量是一个对象或Null,则typeof操作符会返回object;

  虽然在检测基本数据类型时typeof是非常得力的助手,但在检测引用类型的值时 ,这个操作符的用处不大。通常,我们并不是想知道某个值是对象。为此,ECMAScript提供了instanceof操作符,其语法如下:

  result = variable instanceof constructor;

  如果变量是引用类型的实例,那么instanceof操作符就会返回true。

  根据规定,所有引用类型的值都是Object的实例。因此,在检测一个引用类型值和Object构造函数时,instanceof操作符始终会返回true。当然,如果使用instanceof操作符检测基本类型,则该操作符始终返回false,因为基本类型不是对象。

 

时间: 2024-10-20 15:28:05

变量——基本类型和引用类型的值的相关文章

JavaScript基本类型和引用类型的值

JS变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型指的是简单的数据段,而引用类型值那些由多个值构成的对象: 在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值.JS有5种基本数据类型:Undefined, Null,Boolean,Number和String.这5种基本数据类型是按值访问的.因为可以操作保存在变量中的实际的值. 引用类型的值保存在内存中的对象.与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间.

《JavaScript高级程序设计》读书笔记 ---基本类型和引用类型的值

变量.作用域和内存问题 基本类型和引用类型的值ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象.在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值.第3 章讨论了5 种基本数据类型:Undefined.Null.Boolean.Number 和String.这5 种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值.引用类型的值是保存在内存中的对象.与其他语言不同,J

JS 基本类型和引用类型的值

对于引用类型的值,可以为其添加属性和方法,也可以改变和删除其属性和方法.如下: var person = new Object(); person.name = "Jack"; alert(person.name); //"Jack" 以上代码创建了一个对象并将其保存在了变量 person 中.然后,为该对象添加了一个名为 name 的属性,并将字符串值 "Jack" 赋给了这个属性.紧接着,又通过 alert() 函数访问了这个新属性.如果对象

基本类型和引用类型的值 [重温JavaScript基础(一)]

前言: JavaScript 的变量与其他语言的变量有很大区别.JavaScript 变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变.尽管从某种角度看,这可能是一个既有趣又强大,同时又容易出问题的特性,但 JavaScript 变量实际的复杂程度还远不止如此 基本类型和引用类型的值 复制变量值 传递参数 检测类型 基本类型和引用类型的值 ECMAScript 变量可能包含

JS基本类型和引用类型的值

JS中可以把变量分成两部分,基本类型和引用类型. 基本类型比较简单,包括:Undefined.Null.Boolean.Number和String,基本类型值就是简单的数据段:引用类型值可能由多个值构成的对象. 引用类型值保存在内存中,而JS是不能直接访问内存的,所以对于引用类型,操作的不是实际的对象而是对象的引用. 注:string在ECMAScript中不是引用类型,和其他许多语言不同. 接下来主要说明引用类型值的一些问题. 1.动态属性. JS中对象的属性可以动态的添加并且赋值的,比如:

【Java】基本类型和引用类型(值传递)

[关键词] [问题] · 加深对基本类型和引用类型的理解: [效果图] [分析] 參见最后的[參考资料] [解决方式] [代码] public void test() throws Exception { System.out.println("\nint:================="); int i = 2; System.out.println("before:" + i); change1(i); System.out.println("af

基本类型和引用类型的值

一:什么是基本类型和引用类型值 1. 基本类型值指的是简单的数据段 2. 引用类型指那些可能有多个值组成的对象 3. 在赋值变量时,解析器必须确定这个是基本类型值还是引用类型值 4. 有5种基本数据类型:Underfined,Null,Boolean,Unmber和String.这5种可以直接操作保存在变量种的实际值. 5. 引用类型的值保存在内存的对象中,javascript不允许直接访问内存中的位置.操作对象时,实际操作的是对象的引用而不是实际对象.因此,引用类型的值是引用访问的. 二:动态

JavaScript的基本类型和引用类型的值。

ECMAScript变量包含两种数据类型的值:基本类型值和引用类型值. 在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值. 基本类型:string,number,boolean,undefined和null.      基本类型值:简单的数据段,保存在栈内存中同时占有固定大小的空间,按值访问,因此可以操作保存在变量中的实际的值. 引用类型:Object,Array,Date     引用类型值: 由多个值构成的对象,在栈内存中变量保存的实际上是一个地址,这个地址指向堆内存中所

《JS高程》基本类型和引用类型的值学习笔记

ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值. 创建方式类似:创建一个变量并为其赋值. (1)基本类型值和引用类型值比较 基本类型值 引用类型值 简单的数据段 可能由多个值构成的对象 值源自5种基本数据类型:Undefined.Null.Boolean.Number 和 String 值是保存在内存中的对象 在内存中占据固定大小的空间,保存在栈内存中 保存在堆内存中 按值访问 按引用访问 不能添加属性 能动态地添加和删除属性 复制变量值时,创建一个新值(副本)