JS基础进阶1 数据类型

值类型

ECMAScript 5 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。
ECMAScript 6中新增加了一种类型 Symbol。

通常你也可以叫它们为原始类型,或者基础数据类型。

详情见w3cschool中的介绍

引用类型

ECMAScript 中的引用类型有Object 、Array、Function

值类型与引用类型的区别

与所有编程语言一样,值类型存在于stack(栈)中,遵循后进先出的原则,静态分配内存,自动释放内存。引用类型存在于heap(堆)中,堆是内存中的动态区域,当引用类型被创建时会动态分配内存大小,也不会自动释放内存,除非手动设置值为null,故创建对象不应过于泛滥,否则会产生内存问题。

值类型的访问是按值访问,操作的是变量中的实际的值。
引用类型的访问是按其在堆中的引用地址访问,根据其在堆中的地址找到值。

值传递与引用传递(传值与传址)

 var stackVar = "test";

    var heapVar = [0, 1, 2, 3, 4]
    var heapVar2 = heapVar;//引用类型间的相互赋值操作只是引用了同一个内存地址
    var heapVar3 = heapVar;
    heapVar3 =[];//此处赋值了一个新的对象[],相当于变量heapVar3重新指向了一个内存空间

    console.log(heapVar);//0, 1, 2, 3, 4

    heapVar2.unshift(-1);

    function test1(str) {
        str = "stackVar"
    }

    function test2(arr) {
        arr = []; 
    }

    function test3(arr) {
        arr.push(5);
    }

    console.log(stackVar);//test

    test1();

    console.log(stackVar);//test

    console.log(heapVar);//-1,0,1,2,3,4

    test2(heapVar);
    console.log(heapVar);//-1,0,1,2,3,4

    test3(heapVar);
    console.log(heapVar);//-1,0,1,2,3,4,5

引用类型数据的浅拷贝和深拷贝

前面已经说到了,引用类型在传递过程中只是传递的一个地址,传递到函数内进行相关操作会影响外部值。
所以,当我们想避免这种情况时,需要对数据进行复制,有2种情况,如下。

浅拷贝

    var a = {
        k1: "1",
        k2:[1,2]
    }

    function Copy(p) {
        var c = {};
        for (var i in p) {
            c[i] = p[i];
        }
        return c;
    }

    var b = Copy(a);

    b.k1 = "2";
    b.k2.push(3,4)

    console.log(a.k1); //"1"
    console.log(a.k2);//[1,2,3,4]

上例的变量b拷贝了a,但是改变了b的值后,a.k1未受影响,a.k2却受影响,这是因为a.k2是引用类型,
即父子对象存在地址共享,为了解决此问题,正确的复制操作应该为深拷贝。如下

深拷贝

    var a = {
        k1: "1",
        k2: [1, 2]
    }

    function Copy(p, c) {
        var c = c || {};
        for (var i in p) {
            if (typeof p[i] === 'object') {
                c[i] = (p[i].constructor === Array) ? [] : {};
                Copy(p[i], c[i]);
            } else {
                c[i] = p[i];
            }
        }
        return c;
    }

    var b = {};
    b = Copy(a, b);

    b.k1 = "2";
    b.k2.push(3, 4)

    console.log(a.k1); //"2"
    console.log(a.k2);//[1,2]

上例通过递归找到数据中所有的引用类型数据,通过赋值操作将其指向一个新的地址,从而切除浅拷贝中的对象引用地址共享的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值