手记

引用类型、对象拷贝

1.引用类型有哪些?非引用类型有哪些?

JS为了便于操作基本类型,提供了3个特殊的引用类型:Boolean/Number和String(基本类型转引用类型): javascript基本包装类型介绍

  • 引用类型值:(对象、数组、函数、正则)

  • 指的是那些保存在堆内存中的对象,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象

  • 非引用类型:(字符串、数值、布尔值、null和undefined)

  • 指的是保存在栈内存中的简单数据段

2.如下代码输出什么?为什么

  var obj1 = {a:1, b:2};  var obj2 = {a:1, b:2};  console.log(obj1 == obj2);  //1
  console.log(obj1 = obj2);  console.log(obj1 == obj2);  //2
  • 第一个为false,因为obj1和obj2的值虽然相同,但是这两个对象分别保存在堆内存的不同位置,指针各自指向不同的位置

  • 第二个为true,因为obj2将值赋予obj1实际是将存储在变量中的指针赋予obj1,而这个指针指向同一个堆内存位置

3.如下代码输出什么? 为什么

    var a = 1
    var b = 2
    var c = { name: '饥人谷', age: 2 }    var d = [a, b, c]    var aa = a    var bb = b    var cc = c    var dd = d

    a = 11
    b = 22
    c.name = 'hello'
    d[2]['age'] = 3

    console.log(aa)  // 输出为1,因为非引用类型会拷贝并重新创建了一个栈内存空间在原来的a之上
    console.log(bb) // 输出为2,因为非引用类型会拷贝并重新创建了一个栈内存空间在原来的b之上
    console.log(cc) // 输出为{ name: 'hello', age: 3 },因为引用类型是通过指针指向对象所存放的位置,直接进行拷贝,则将该指针赋值给cc,所以cc的值和c一样
    console.log(dd) // 输出为{1,2,{ name: 'hello', age: 3 }},因为引用类型是通过指针指向对象所存放的位置,直接进行拷贝,则将该指针赋值给dd,所以dd的值和d一样

4.如下代码输出什么? 为什么

    var a = 1
    var c = { name: 'jirengu', age: 2 }    function f1(n){
      ++n
    }    function f2(obj){
      ++obj.age
    }

    f1(a) 
    f2(c) 
    f1(c.age) 
    console.log(a) //输出为1,函数内的局部变量不影响全局变量的值
    console.log(c) //输出为{ name: 'jirengu', age: 3 },f2进行函数运算后age为3,因为引用类型的特点,所以值改变,而进行f1的函数运算时,由于是单独提取出age的值进行运算,相当于转变为非引用类型,所以值不受影响

5.过滤如下数组,只保留正数,直接在原数组上操作

js中splice()的强大(插入、删除或替换数组的元素)

    var arr = [3,1,0,-1,-3,2,-5]    function filter(arr){        for(var i = 0; i < arr.length; i++) {            if(arr[i] <= 0){
                arr.splice(i,1);  
                i--;
            }
        }
    }
    filter(arr)    console.log(arr) // [3,1,2]

6.过滤如下数组,只保留正数,原数组不变,生成新数组

JavaScript中数组slice和splice的对比小结

 方法一: var arr = [3,1,0,-1,-3,2,-5]          var j = 0;          function filter(arr){              var newArr = [];              for(var i = 0; i < arr.length; i++){                  if(arr[i] >= 0) {
                      newArr[j] = arr[i];
                      j++;
                  }
               }              return newArr;
          }          var arr2 = filter(arr)          console.log(arr2) // [3,1,2]
          console.log(arr)  // [3,1,0,-1,-2,2,-5]方法二:var arr = [3,1,0,-1,-3,2,-5]var arr2 = arr.slice();function filter(arr2) {    for(var i=0;i<arr2.length;i++) {        if(arr2[i]<=0) {
            arr2.splice(i,1);
            filter(arr2);
          }
    }
 }
filter(arr2);console.log(arr);console.log(arr2);

7.写一个深拷贝函数,用两种方式实现

JS中的hasOwnProperty()和isPrototypeOf()属性实例详解

    方法一:
    obj = {            age:100,            one: null,            finder: {                name: 'jirengu',                sex: 'nv'
            }
        }        function copy(obj) {            var newObj = {};            for(var key in obj) {                if(obj.hasOwnProperty(key)) {   // hasOwnProperty 是检测对象在排除原型链的情况下是否具有某个属性。
                    if(typeof obj[key] === 'number' 
                        || typeof obj[key] === 'boolean' 
                        || typeof obj[key] === 'string' 
                        || typeof obj[key] === 'undefined'
                        || obj[key] === null) {
                        newObj[key] = obj[key];
                    }else{
                        newObj[key] = copy(obj[key]);
                    }
                }
            }            return newObj;
        }        var obj3 = copy(obj);
        obj.finder.name = '饥人谷'
        console.log(obj3);

方法二:function copy(obj){    var newobj = JSON.parse(JSON.stringify(obj));    return newobj;
}var obj2 = copy(obj1)console.log(obj2)



作者:饥人谷_米弥轮
链接:https://www.jianshu.com/p/02a625919046


0人推荐
随时随地看视频
慕课网APP