JS的引用类型和基本类型(传值和传引用)

首先基本类型的数据是存放在栈内存中的,而引用类型的数据是存放在堆内存中的。

基本类型:

    var num1 = 5;
    var num2 = num1;

执行结果:
JS的引用类型和基本类型(传值和传引用)

基本类型的复制就是在栈内存中开辟出了一个新的存储区域用来存储新的变量,这个变量有它自己的值,所以如果其中一个的值改变,则不会影响到另一个

引用类型:

    var object1 = new Object();
    var object2 = object1;
    object2.name = 'jhon';
    alert(object1.name); //jhon

JS的引用类型和基本类型(传值和传引用)
定义了一个对象其实是在栈内存中存储了一个指针,这个指针指向堆内存中该对象的存储地址。两个指针都指向同一个对象,所以若其中一个修改了,则另一个也会改变。

基本类型的数据是没有属性和方法的,引用类型才会有,但是为什么String类型却又那么多方法呢?

var string = "aaa";

var string2 = string.substring(0);   //aaa

为了方便程序员对这类的基本类型数据比较方便的操作,在底层做了一些工作,其实这段代码相当于:

var string = new String("aaa");

var string2 = string.substring(0);

string = null;

(1)创建一个String类型的实例 (使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一
行代码的执行瞬间,然后立即被销毁 )

(2)在实例上调用指定方法

(3)销毁该实例

经过这三步,字符串值就变得和对象一样了,在Boolean Number中也是这样
String Boolean Number 这三种类型也叫做 基本包装类型

再看看下面代码:

 function setName(obj) {
     obj.name = "Nicholas";
     obj = new Object(); //改变obj的指向,此时obj指向一个新的内存地址,不再和person指向同一个
     obj.name = "Greg";
 }
 var person = new Object();
 setName(person);  
 alert(person.name);  //"Nicholas"

当创建obj对象 obj = new Object(); 时,来看看这时person和obj的关系图:
JS的引用类型和基本类型(传值和传引用)
引用传递的是指针的值,obj=new Object()改写了自己的指向,并不会影响到person的指向,这种方式就是按引用传递

var person=new Object(); 
var obj = person;  // 赋值
obj.name="ABC"; 
obj=new Object(); 
obj.name="BCD"; 
console.log(person.name);// ABC  并没有影响person的指向

对象引用本身是传递引用地址,重新初始化变量会改变引用地址,不会更改原变量.