javascript 基本数据类型、引用数据类型

阅读目录

 

数据类型

1.   ECMAScript变量包含两种不同类型的值:基本类型值、引用类型值;

2.   基本类型值:指的是保存在栈内存中的简单数据段;

3.   引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针指向内存堆中实际的值;

* 理解一下 栈内存 和 堆内存:

 

* 也就是上边 2、3条所说的意思:基本数据类型在栈中以简单数据段的方式保存; 引用类型 在栈中保存的是指向引用对象的地址; 

两种访问方式

4.   基本类型值:按值访问,操作的是他们实际保存的值;

5.   引用类型值:按引用访问,当查询时,我们需要先从栈中读取内存地址,然后再顺藤摸瓜地找到保存在堆内存中的值;

 

两种类型复制

 基本类型变量的复制:

 从一个变量向一个变量复制时,会在栈中创建一个新值,然后把值复制到为新变量分配的位置上,改变源数据不会影响到新的变量(互不干涉);

引用类型变量的复制:

复制的是存储在栈中的指针,将指针复制到栈中为新变量分配的空间中,而这个指针副本和原指针指向存储在堆中的同一个对象,复制操作结束后,两个变量实际上将引用同一个对象;通过一个指针找到这个公共的对象,对其进行改变,然后我们再通过另一个指针查找到这个公共的对象,实际上,得到的是已经改变后的这个对象;

函数参数的传递

1.   ECMA中所有函数的参数都是按值传递的;

在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量,在向参数传递引用类型的值时,会把这个值所在的堆中的地址复制给一个局部变量;

基本数据类型传递参数

  funciton addTen(num){

    num+=10;

    return num;

  }

  var a=20;

  var result=addTen(count); // 相当于 addTen(num = count) 的过程,即,把 count 赋值给局部变量 num, 然后再执行 addTen() 作用域内的代码

  alert(count);//20

  alert(resullt);//30

  执行结果是:20和30。在这段代码中,将变量count当做参数传递给了函数addTen,也就是相当于将变量count的值复制给了函数addTen的参数。这时addTen的参数num可以看做是函数内部的一个变量。在上段代码中,就相当于两个基本数据类型变量之间的值复制。而基本数据类型都有自己独立的内存地址,所以num和count是没有任何关系的,他们只是值相等而已,函数执行完毕后,count的值并没有改变。而函数外面的result是被直接赋值的,所以result的值就是函数的结果30。

 

引用类型传递参数

  function setName(obj){

    obj.name="JCY";

  }

  var person=new Object(); // 此时 person 存的是 new Object() 在堆中的地址

  setName(person);  // 相当于 setName(obj = person) 的过程,即,把 person 赋值给局部变量 obj, 然后再执行 setName() 作用域内的代码

  alert(person.name);// JCY

  执行结果是:JCY。在这段代码中,函数setName的作用是给obj对象添加了一个属性name并给该属性赋值为"JCY",因为obj是引用类型,所以这里属于是将引用类型person赋值给了obj,也就是说person和obj引用了一个内存地址,所以当给obj新加了属性name时,在函数外面的person也跟着改变,最后person.name 的结果为JCY。

引用类型传递参数到底传的是值还是引用

  function setName(obj){

    obj.name="ABC";

    obj=new Object(); // 这句 改变了 局部变量obj 的指向

    obj.name="BCD";

  }

  var person=new Object(); // 此时 person 存的是 new Object() 在堆中的地址

  setName(person); // 相当于 setName(obj = person), 即,把 person 赋值给局部变量 obj, 然后再执行 setName() 作用域内的代码

  alert(person.name);// ABC

  执行结果是:ABC。实例3与实例2的区别是在函数中又加了2行代码,在给obj引用的对象(也就是 person所引用的对象) 新加一个属性name并赋值后, 又将局部变量obj重新指向了一个新的对象(new Object()),然后给这个新对象添加了name属性,并赋了值“BCD”。所以,在我们输出 person.name 的时候,应该输出最后一次对 person 所引用的对象的操作 完成后的 name 值(也就是 obj.name = "ABC" 这句)。

  所以,也印证了,ECMA中所有函数的参数都是按值传递的,这句话;

两种变量类型检测

1.   Typeof操作符是检测基本类型的最佳工具;

2.   如果变量值是null 或者 对象,typeof 将返回“object”;

3.   Instanceof用于检测引用类型,可以检测到具体的,它是什么类型的实例;

4.   如果变量是给定引用类型的实例,instanceof操作符会返回true;

 

 
 
参考:
 
 
 

 

posted @ 2018-04-09 20:45  驸马爷  阅读(245)  评论(0编辑  收藏  举报