重点--基本数据类型和引用数据类型(对象)

2019-06-22  本文已影响0人  潘肚饿兵哥哥

var a = 123;
var b = a;
a++;
console.log("a = "+a);
console.log("b = "+b);
\color{rgba(3, 101, 100, .8)}{返回值:}
"a = 124"
"b = 123"
\color{rgba(254, 67, 101, .8)}{从上面例子看,b和a虽然赋值了,但他们是独立的个体,一个值变化不会影响其他值}

var obj = new Object();
    obj.name = "孙悟空";
    var obj2 = obj;
    //修改obj的name属性
    obj.name = "猪八戒";
    console.log(obj.name);
    console.log(obj2.name);

返回值:


image.png

\color{rgba(254, 67, 101, .8)}{这里按照上面第一个例子的逻辑应该不会受到影响}
\color{rgba(254, 67, 101, .8)}{但是却两个值都变成了赋值后的值,这就是基本数据类型和引用数据类型之间的不同之处}

\color{rgba(254, 67, 101, .8)}{JS中的变量都是保存到栈内存中的,}

  • \color{rgba(3, 101, 100, .8)}{变量名和值都存在栈内存中的,}

  • \color{rgba(3, 101, 100, .8)}{基础数据类型的值就存在栈内存中}

    • \color{rgba(254, 67, 101, .8)}{var a=123; var b=a;相当于在栈内存中另给b一个区域,给他一个和a相等的值}
    • \color{rgba(254, 67, 101, .8)}{现在相当于有了一个a=123;和一个b=123;两个内存空间}
    • \color{rgba(254, 67, 101, .8)}{他们的值虽然相等,但不共用同一个内存地址,各是各的地址,各自独立存在}
    • \color{rgba(254, 67, 101, .8)}{赋完值之后,他们俩就没关系了,所以其中一个变量产生变化,不影响另一个}

\color{rgba(254, 67, 101, .8)}{JS中的对象是保存到堆内存中的}

  • \color{rgba(3, 101, 100, .8)}{每创建一个新的对象,就会在堆内存中开辟出一个新的空间}
  • \color{rgba(3, 101, 100, .8)}{这个空间的内存地址会作为变量的值存在栈内存中}
    • \color{rgba(254, 67, 101, .8)}{var obj = new Object();新建一个对象,声明的变量名同样存在栈内存中}
    • \color{rgba(254, 67, 101, .8)}{基础数据类型的存储是在栈内存中以键值对的形式存放的}
    • \color{rgba(254, 67, 101, .8)}{对象也是一样以键值对形式存在栈内存中,只不过,键的部分是变量名,而值的部分是一个内存地址}
    • \color{rgba(254, 67, 101, .8)}{这个内存地址是一个堆内存的地址,这个堆内存里装的就是这个对象的值}
    • \color{rgba(254, 67, 101, .8)}{所以他们不一样的地方就在于,基础数据类型【变量名:值】以键值对的形式存在栈内存里}
    • \color{rgba(254, 67, 101, .8)}{而引用数据类型同样是【变量名:值】这里的值就变成了内存地址}
    • \color{rgba(254, 67, 101, .8)}{【变量名:内存地址(值)】-->【内存地址-->值】以这样的形式存在栈内存里}
    • \color{rgba(254, 67, 101, .8)}{对象的内存地址就是引用,无论是给对象添加属性,还是赋值都一样}
    • \color{rgba(254, 67, 101, .8)}{和基础数据类型一样,赋值就会把原值赋给新的变量,但是这个值不是一个确定的值}
    • \color{rgba(254, 67, 101, .8)}{他是一个地址,无论怎么操作,都是操作栈内存中的值(内存地址),而这个值永远指向同一个区域}
    • \color{rgba(254, 67, 101, .8)}{所以,修改基本数据类型值的话,他们本身互不影响,但是给一个对象赋值,其中一个产生变化,另一个也会变,因为他们本身就是一个值}

\color{rgba(254, 67, 101, .8)}{设置obj2为null}
\color{rgba(254, 67, 101, .8)}{obj2 = null;这不会影响obj的值,因为只是设置地址值为空了,并没有操作真正的堆内存里的值}

image.png

var obj3 = new Object();
var obj4 = new Object();
obj3.name = "沙和尚";
obj4.name = "沙和尚";
console.log(obj3 == obj4);
\color{rgba(3, 101, 100, .8)}{他们的返回值是 false,因为这是两个对象,等于开了两个内存空间,只不过两个内存空间中存放的值是一样的}
\color{rgba(3, 101, 100, .8)}{每次new都会创建一个新的空间}
\color{rgba(3, 101, 100, .8)}{这里虽然对象的值相同,但是地址值不同,而obj3 == obj4比较的是地址值}


\color{rgba(254, 67, 101, .8)}{总结:}
\color{rgba(254, 67, 101, .8)}{基本数据类型保存的是值}
\color{rgba(254, 67, 101, .8)}{引用数据类型保存的是引用的内存地址}


<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            
            /*
             * 基本数据类型
             *  String Number Boolean Null Undefined
             * 
             * 引用数据类型
             *  Object
             * 
             * JS中的变量都是保存到栈内存中的,
             *      基本数据类型的值直接在栈内存中存储,
             *      值与值之间是独立存在,修改一个变量不会影响其他的变量
             * 
             *      对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,
             *      而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,
             *      当一个通过一个变量修改属性时,另一个也会受到影响
             */
            
            var a = 123;
            var b = a;
            a++;
            
            /*console.log("a = "+a);
            console.log("b = "+b);*/
            
            var obj = new Object();
            obj.name = "孙悟空";
            
            var obj2 = obj;
            
            //修改obj的name属性
            obj.name = "猪八戒";
            
            
            
            /*console.log(obj.name);
            console.log(obj2.name);*/
            
            //设置obj2为null
            obj2 = null;
            
            /*console.log(obj);
            console.log(obj2);*/
            
            var c = 10;
            var d = 10;
            //console.log(c == d);
            
            var obj3 = new Object();
            var obj4 = new Object();
            obj3.name = "沙和尚";
            obj4.name = "沙和尚";
            
            /*console.log(obj3);
            console.log(obj4);*/
            
            /*
             * 当比较两个基本数据类型的值时,就是比较值。
             * 而比较两个引用数据类型时,它是比较的对象的内存地址,
             *      如果两个对象是一摸一样的,但是地址不同,它也会返回false
             */
            console.log(obj3 == obj4);
            
            
        </script>
    </head>
    <body>
    </body>
</html>

上一篇 下一篇

猜你喜欢

热点阅读