JavaScript的基本类型和对象引用总结

写在前面

ECMAScirpt 变量有两种不同的数据类型:基本类型引用类型。或者也可以叫原始类型对象类型。初次之外还有很多其他的叫法,不过都是根据这两种类型的特点进行命名的。

基本类型

ES5拥有5种基本数据类型,非别是:undefinedbooleannumberstringnull,ES6中多了一种基本数据尅性,叫symbol,Symbol的目的就是为了实现一个唯一不重复不可变的值,任何一个Symbol都是唯一的,不会和其他任何Symbol相等。
基本类型的访问是按值访问的,就是说你可以操作保存在变量中的实际的值。基本类型有以下几个特点:

1.值不可变

任何的方法都不可以改变一个基本类型的值,看例子:

    <script>
        var name = "LAN";
        name.toLowerCase();
        console.log(name);
    </script>
Output:LAN

对name调用了toLowerCase()方法,再输出name变量,依然是大写LAN。因为toLowerCase()会返回一个新的字符串回来。

2.不能添加属性和方法
    <script>
        var name = "LAN";
        name.do = function(){
            console.log("name.do");
        }
        name.do();
    </script>
Output:name.do is not a function

控制台爆出错误,说name.do不是一个function,说明不能给基本类型添加属性或者方法。

3.基本类型比较为值比较

值比较是什么意思呢?意思就是只要两个变量的值相等,那么就认为就俩个变量就是相等的。举个例子:

    <script>
        var a = 1;
        var b = 1;
        console.log(a === b);
    </script>
Output:true

这里的a、b两个变量的值都为1,通过输出可知a变量等于b变量。

4.基本类型的变量是存放在栈区的

如果我们定义了以下几个变量:

    <script>
        var name = "LAN";
        var age = 22;
        var sex = "男";
    </script>

那么这些变量在栈区里面的存在形式是这样的:
栈区表现形式
栈区里面包括了变量的标识符和变量的值,也就是上图的key和value。

引用类型

引用类型其实也就是对象。对象里面可以有属性和方法,也就是引用类型可以拥有属性和方法。下面是一些引用类型的特点:

1.值可变

我们可以为对象添加或者删除属性和方法,看代码:

    <script>
        var person = {};
        person.name = "LAN";
        person.age = 22;
        person.sayName = function() {
            console.log(this.name);
        };
        person.sayName();
        delete person.name;
        person.sayName();
    </script>
Output:
LAN
undefined

上面代码说明引用类型可以拥有属性和方法,并且是可以动态改变的。

2.引用类型的值同时保存在栈内存和堆内存中

对于javascript,我们不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。实际上,我们是操作对象的引用,所以引用类型的值是按引用访问的。
简单来说,要存储引用类型的变量,需要栈空间、堆空间同时使用,栈区内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址。假如我们定义了如下几个对象:

    <script>
        var student1 = {name: "张三"};
        var student2 = {name: "李四"};
        var student3 = {name: "王五"};
    </script>

那么这几个对象在内存中的存储形式如下:
引用类型存储

引用类型比较是引用比较

这个特点意思是说,两个对象比较,比较的是栈区里面存储的引用地址,也就是映射到堆区的那个地址。举个例子:

    <script>
        var student1 = {name: "张三"};
        var student2 = {name: "张三"};
        console.log(student1 === student2);
    </script>
Output:false

虽然说student1和student2的值是一样的,但是存储到堆区里面的地址是不相同的,所以相比较为false。

简单赋值

基本类型变量进行相互赋值,两个变量依然是相互独立的,举个例子:

    <script>
        var a = 1;
        var b = a;
        a++;
        console.log(a);
        console.log(b);
    </script>
Output:
2
1

赋值之后,两个变量依然是独立的,可以进行独立操作不受互相影响。
赋值栈区变化

对象引用

引用类型变量进行相互赋值,是将栈区存放的地址进行相互赋值,结果就是两个对象指向同一块堆地址,也就是说两个赋值之后的两个对象其实是一个对象,是完全相等的。

    <script>
        var a = {};
        var b = a;
        a.name = "lan";
        console.log(a.name);
        console.log(b.name);
        console.log(a === b);
    </script>
Outout:
lan
lan
true

就如同之前所说,引用类型比较比较的是地址,现在两个对象指向同一个地址,所以是相等的,固然输出true。下面是内存示意图:
引用类型赋值
因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值