JavaScript基本数据类型和引用数据类型

ECMAScript包含两种不同数据类型的值:基本类型值和引用类型值。基本类型值指的是简单的数据段,而引用类型值那些可能有多个值构成的对象。

在进行变量赋值时,解析器必须确定这个值是基本类型值还是引用类型值。常用的5中基本数据类型为:Undefined、Null、Boolean、Number和String。基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。而引用类型的值是保存在内存中的对象。JavaScript不允许直接访问内存中的位置,即不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。因此,引用类型的值是按引用访问的。

1. 动态的属性

对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。例如:


  1. var person = new Object(); 
  2.  
  3. person.name = "John"; 
  4.  
  5. alert(person.name); //"John" 

只要对象不被销毁或者这个属性不被删除,这个属性就一直存在。但我们不能给基本类型的值添加属性,尽管并不会导致任何错误。

2. 复制变量值

如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后将该值复制到为新变量分配的位置上,例如:


  1. var num1 = 5; 
  2.  
  3. var num2 = num1; //5 

下图形象地展示了复制基本类型值的过程:

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


  1. var obj1 = new Object(); 
  2.  
  3. var obj2 = obj1; 
  4.  
  5. obj1.name = "John"; 
  6.  
  7. alert(obj2.name); //"John" 

3. 传递参数

ECMAScript中所有函数的参数都是按值传递的。把函数外部的值复制给函数内部的参数,就和把一个变量的值复制给另一个变量一样。无论传递的是基本类型的值还是引用类型的值。这里需要注意,访问变量有按值和按引用两种方式,但参数只能按值传递。

在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数)。例如:


  1. function addTen(num){ 
  2.  
  3. num += 10; 
  4.  
  5. return num; 
  6.  
  7.  
  8. var count = 20; 
  9.  
  10. var result = addTen(count); 
  11.  
  12. alert(count); //20,没有变化 
  13.  
  14. alert(result); //30 

参数实际上是函数的局部变量。参数num和变量count互不认识,它们只是具有相同的值。假如num是按引用传递的,那么count的值也会变成30,从而反应函数内部的变化。

在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反应在函数外部。例如:


  1. function setName(obj){ 
  2.  
  3. obj.name = "John"; 
  4.  
  5.  
  6. var person = new Object(); 
  7.  
  8. setName(person); 
  9.  
  10. alert(person.name); //"John" 

在这个函数内部,obj和person引用的是同一个对象。换句话说,即使这个值是按值传递的,obj也会按引用来访问同一个对象。于是,在函数内容为obj添加nama属性在函数外的person对象也有所反应,因为person指向的对象在堆内存中只有一个,而且是全局对象。有许多开发者认为,在函数内容修改的对象会在全局作用域中反应出来,说明参数是按引用传递的,这个观点其实是错误的,看下面的代码:


  1. function setName(obj){ 
  2.  
  3. obj.name = "John"; 
  4.  
  5. obj = new Object(); 
  6.  
  7. obj.name = "Evan"; 
  8.  
  9.  
  10. var person = new Object(); 
  11.  
  12. setName(person); 
  13.  
  14. alert(person.name); //"John" 

如果person是按引用传递的,那么person就会自动被修改为指向其name属性为"Evan"的新对象,但我们访问person.name时发现其值仍然为"John",这说明即使在函数内部修改了参数的值,但原始的引用仍然保持不变。实际上,在函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象在函数执行完成之后会立即销毁。

4. 检测类型

要检测一个值是不是基本数据类型,typeof操作符是最佳工具。它可以检测一个变量是字符串、数值、布尔值还是undefined。如果一个变量是对象或null,则typeof操作符会返回object。

但是在检测引用类型的值时,typeof用处就不那么大了,通常我们并不想知道某个值是对象,而想知道它是什么类型的对象,此时可以使用instanceof操作符,如果变量是给定引用类型的实例,那么instanceof操作符就会返回true。例如:


  1. alert(person instanceof Object);    //变量person是Object吗? 
  2. alert(colors instanceof Array);    //变量colors是Array吗? 
  3. alert(pattern instanceof RegExp);    //变量pattern是RegExp吗? 

所有引用类型的值都是Object的实例。因此,在检测一个引用类型的值或Object构造函数时,instanceof都会返回true。当用instanceof操作符检测一个基本类型的值时,都会返回false,因为基本类型不是对象。

作者:一刻孤独

来源:51CTO

时间: 2024-08-30 00:36:06

JavaScript基本数据类型和引用数据类型的相关文章

java数据-java中键值对数据类型属于引用数据类型吗

问题描述 java中键值对数据类型属于引用数据类型吗 java中键值对数据类型属于引用数据类型吗,可以进行加减乘除操作吗 解决方案 你说像 Map接口的子类?这类引用类型的对象是不能直接进行加减乘除的.能进行加减乘除的只有基本类型和基本类型的包装类.当然如果你Map里放的值是基本类型,比如 Map对象map.put("key",1); 这样的存储你是可以通过 map.get("key") 获取 键值对的值,再对键值对的值进行运算的.但不能对map进行直接运算 解决方

Javascript学习笔记一 之 数据类型_基础知识

一.数据类型 Javascript是一种弱类型的脚本语言,它一共有6种数据类型,又被分为基础数据类型,特殊数据类型,复合数据类型. 1.基础数据类型:数值型,字符串型,布尔型 2.特殊数据类型:null,undefined(区别在于null需要显性赋值,而undefined表示没有赋值) 3.复合(引用)数据类型:Object(数组是特殊的对象) 注:理解基础数据类型和引用数据类型的区别.如函数参数传递 二. 包装类和基础数据类型的关系 对于基础数据类型,都有相应的包装类(Object对象)与之

【java笔记】关于引用数据类型的内存使用原理

1.java声明的数据类型在java内存中的使用情况 基本数据类型和引用数据类型使用的内存情况是不同的,基本数据类型只在栈中开辟内存,一旦使用结束(例如函数或方法内的数据),栈中的内存就会自动释放,然而引用数据类型会将对象存放在栈中,而将真正的值存放在堆中,不可以直接操作堆内存中的数据空间,只能通过堆内存中的值对应的地址赋值给栈中的对象,通过栈中的对象来操作数据,所以栈中的对象记录的是堆中数据的地址. 2.堆中数据特点 (1)堆中数据都会有一个对应的地址: (2)堆中数据声明后,都会有默认值,默

解析JavaScript中的不可见数据类型

 这篇文章主要是对JavaScript中的不可见数据类型进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 JS提供了一些内置对象.函数和构造器供我们编程,如Math.parseInt.Object.Array等.这些都是可见的,编程时可以使用的.比如我可以new Object 或 new Array.   有一些则是不可见的,这些对象只能由引擎在特殊的情形提供.这些类型的对象往往还被消减了一些功能.下面列举一些   一.Arguments 类型 Arguments 类型 不能由程序

java中什么时候定义类属性用基本数据类型,什么时候用引用数据类型?

问题描述 java中什么时候定义类属性用基本数据类型,什么时候用引用数据类型? 例如什么时候定义Integer i=1; 什么时候定义int i=1; 又如Long i=2; long i=2 求解释 解决方案 Integer.Float等这些叫做"外覆类",相比较int float等类型来说,它们可以被添加到ArrayList等集合中,因为这些集合需要引用类型. 更详细的介绍http://my.oschina.net/u/1861837/blog/335581?fromerr=GTp

对象-java初学者关于引用数据类型 强制转换的问题

问题描述 java初学者关于引用数据类型 强制转换的问题 class TestDemo7{ public static void main(String[] args) { Animal a=new Dog("旺财",2); System.out.println("名字:"+a.getName()); System.out.println("年龄:"+a.getAge()); a.eat(); Dog dog=(Dog) a;// 强转为Dog类

java代码-java引用数据类型的问题,请大神解释下标注的问题.....

问题描述 java引用数据类型的问题,请大神解释下标注的问题..... import java.util.Scanner; public class Bank implements Runnable { Acount acount; public Bank(Acount a) -->这个构造方法的含义? { this.acount=a; } public void run() { Scanner input=new Scanner(System.in); System.out.println(&qu

java常量-java中常量的数据类型不单可以是基本数据类型,也可以引用数据类型,这种说法对吗

问题描述 java中常量的数据类型不单可以是基本数据类型,也可以引用数据类型,这种说法对吗 java中常量的数据类型不单可以是基本数据类型,也可以引用数据类型,这种说法对吗 解决方案 对 常量是程序中一些不会被改变的数据 解决方案二: 可以啊,引用类型一旦定义为final常亮后,就不能再重新指向其他的对象了.

《数据结构与算法 C语言版》—— 1.4数据类型与抽象数据类型

1.4数据类型与抽象数据类型 1.4.1数据类型 数据类型是和数据结构密切相关的一个概念,它最早出现在高级程序语言中,用以刻画(程序)操作对象的特性.在用高级程序语言编写的程序中,每个变量.常量或表达式都有一个它所属的确定的数据类型.类型显式或隐含地规定了在程序执行期间变量或表达式所有可能的取值范围,以及在这些值上允许进行的操作.因此,数据类型是一个值的集合和定义在此集合上的一组操作的总称.例如,C语言中的整型变量,其值为某个区间上的整数(依赖于机器),定义在其上的操作为加.减.乘.除和取模等算