乐趣区

关于javascript:JS基本数据类型和引用数据类型的区别

数据类型

  1. ECMAScript 变量蕴含两种不同类型的值:根本类型值、援用类型值;
  2. 根本类型值:指的是保留在 内存中的简略数据段;
  3. 援用类型值:指的是那些保留在 内存中的对象,意思是,变量中保留的实际上只是一个指针,这个指针指向内存堆中理论的值;

两种拜访形式

  1. 根本类型值:按值拜访,操作的是他们理论保留的值;
  2. 援用类型值:按援用拜访,当查问时,咱们须要先从栈中读取内存地址,而后再顺藤摸瓜地找到保留在堆内存中的值;

两种类型复制
根本类型变量的复制:
从一个变量向一个变量复制时,会在栈中创立一个新值,而后把值复制到为新变量调配的地位上,扭转源数据不会影响到新的变量 (互不干涉);
援用类型变量的复制:
复制的是存储在栈中的指针 ,将指针复制到栈中为新变量调配的空间中,而这个指针正本和原指针执行存储在堆中的同一个对象,复制操作完结后,两个变量实际上将援用同一个对象;因而 扭转其中的一个,将影响另一个

函数参数的传递
1、ECMA 中所有函数的参数都是按值传递的
在向参数传递根本类型的值时,被传递的值会被复制给一个 局部变量 ,在向参数传递援用类型的值时,会把这个值在内存的地址复制给一个 局部变量
根本数据类型传递参数

 funciton addTen(num){
    num+=10;
    return num;
  }
  var count=20;
  var result=addTen(count);
  alert(count);//20
  alert(resullt);//30 

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

援用类型传递参数

 function setName(obj){obj.name="LSN";}
  var person=new Object();
 setName(person);
 alert(person.name); // LSN 

执行后果是:LSN。
在这段代码中,函数 setName 的作用是给 obj 对象增加了一个属性 name,并给该属性赋值为 ”LSN”,因为obj 是援用类型,所以这里属于是将援用类型 person 赋值给了 obj,也就是说personobj援用了一个内存地址,所以当给 obj 新加了属性 name 时,在函数里面的 person 也跟着扭转,最初 person.name 的后果为 LSN。

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

 function setName(obj){
    obj.name="ABC";
    obj=new Object();
    obj.name="BCD";
  }
  var person=new Object();
 setName(person);
 alert(person.name); // ABC 

执行后果是:ABC。
实例 3 与实例 2 的区别是在函数中又加了 2 行代码,在给 obj 对象新加一个属性 name 并赋值后又将 obj 定义成了一个新的对象(new Object()),定义新对象后又 name 赋上新的值“BCD”。
这个时候如果是按援用传递的话,那么最初 person 对象就会主动批改为指向其 name 属性为 ”BCD” 的新对象,但最初显示的却是“ABC”,这阐明即便在函数外部批改了参数的值,但原始的援用还放弃不变。
实际上,当在函数外部 obj=new Object() 时 这个新的 obj 就曾经成为函数外部的部分对象了,这个对象会在函数执行结束后主动销毁。

两种变量类型检测

  1. typeof 操作符是检测根本类型的最佳工具;
  2. 如果变量值是 nul 或者对象,typeof 将返回“object”;
  3. Instanceof 用于检测援用类型,能够检测到具体的,它是什么类型的实例;
  4. 如果变量是给定援用类型的实例,instanceof 操作符会返回 true;

补充:根本包装类型 (包装对象)
先看下以下代码:

var s1 = "helloworld";
var s2 = s1.substr(4); 

下面咱们说到字符串是根本数据类型,不应该有办法,那为什么这里 s1 能够调用 substr() 呢?
ECMAScript 还提供了三个非凡的援用类型 BooleanStringNumber。咱们称这三个非凡的援用类型为 根本包装类型 ,也叫 包装对象

也就是说当读取 stringbooleannumber这三个根本数据类型的时候,后盾就会创立一个对应的根本包装类型对象,从而让咱们可能调用一些办法来操作这些数据.

所以当第二行代码拜访 s1 的时候,后盾会主动实现下列操作:

  • 创立 String 类型的一个实例;// var s1 = new String("helloworld");
  • 在实例上调用指定办法;// var s2 = s1.substr(4);
  • 销毁这个实例;// s1 = null;

正因为有第三步这个销毁的动作,所以根本数据类型不能够增加属性和办法,这也正是根本装包类型和援用类型次要区别:对象的生存期

应用 new 操作符创立的援用类型的实例,在执行流来到以后作用域之前都是始终保留在内存中。主动创立的根本包装类型的对象,则只存在于一行代码的执行霎时,而后立刻被销毁。

作者:公子七
链接:https://www.jianshu.com/p/a32…
起源:简书
著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。

退出移动版