JS引用那些事儿

采坑场景

有时,在处理变量时,我们会忘记考虑变量的类型。比如,我们只是想处理一份数据,但并不想改变原数据。比如下面这样:

let obj = {
   id :1
}

如果,此时,你想重新copy一份obj,并添加一些属性,用来在别处使用。

let bak = obj;
bak.name = 'obj';
console.log(bak);    //  {id: 1, name: "obj"}
console.log(obj);    //  {id: 1, name: "obj"}

正确的做法:如果只是简单copy对象的属性,可以:let bak = Object.assign({}, obj),即把obj的属性,复制到一个空对象。

原因解析

为什么 bak.name = 'obj'操作,会导致obj也跟着修改了呢?

真正的原因就是,obj的数据类型是对象。在JS中 ,对象属于引用类型。什么意思?就是说,操作对象事,并不是直接操作内存,而是在操作对象的引用,这个引用指向的才是内存。上面的let bak = obj,相当于引用赋值。换句话说,这么操作之后,bakobj在内存中,指向的是同一个地址。如果修改了其中任何一方,另一个都会受影响。

案例验证

  • JS中的数据类型,简单可分为 基本类型引用类型
    基本类型:UndefinedNullBooleanNumberString
    引用类型:Object
  • 特殊的是,如果打印 typeof null,你会惊奇地发现,结果是 object。这就很奇怪了。既然Null算是对象,为什么还要在数据类型中单独列出呢?其实,null真正的含义是空指针对象,即不指向内存中的任何地址,特指那些没有设置值得对象。

    基本类型的数据,在进行复制等操作时,会重新分配内存,用来放置新数据(值传递)。而引用类型,则是把简单把引用值复制给新对象(地址传递)。


为了更好理解基本类型和引用类型,进行以下验证:
  • 初始化一个变量,调用函数处理变量,对比处理前后的变量值

这里写图片描述

从上面的图 和下面的代码,可以看出,基本类型直接对参数进行处理,不会影响原来的值,而引用类型则会影响。只要,在操作数据时,稍稍注意下类型,就可以避免类型采坑的问题了。

实验代码

(function () {
     for (let i = 1; i < 7; i++) {
         printResult(i);
     }
 })();
// 打印结果
function printResult(type) {
    let data = '',
        result = '',
        initObj = {
            id: 1,
            name: 'init'
        },
        initArr = ['first'];
    switch (type) {
        case 1: // Null
            data = null;
            result = handleObj(data);
            break;
        case 2: // Boolean
            data = true;
            result = handleObj(data);
            break;
        case 3: // Number
            data = 1;
            result = handleObj(data);
            break;
        case 4: // String
            data = 'before';
            result = handleObj(data);
            break;
        case 5: // Object
            data = initObj;
            result = handleObj(initObj);
            break;
        case 6: // Array
            data = initArr;
            result = handleObj(initArr);
            break;
    }
      console.log('处理前:  ', data);
      console.log('%c 处理后:  ', 'color:green;font-weight:bold', result);
}
// 处理变量
function handleObj(param) {
     if (typeof param === 'boolean') {
         return param = false;
     }
     if (typeof param === 'number') {
         return param = 0;
     }
     if (typeof param === 'string') {
         return param = 'after';
     }
     if (typeof param === 'object') {
         if (param === null) {
             param = 'null被改变';
         }
         if (Array.isArray(param)) {
             param.push('add');
         }
         if (param instanceof Object) {
             param.name = 'object';
         }
         return param;
     }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值