美文网首页
指针和引用

指针和引用

作者: 撑船的摆渡人 | 来源:发表于2019-06-11 20:41 被阅读0次

    为什么对象不相等?

    var obj1 = { name: 'haolucky' }
    var obj2 = { name: 'haolucky' }
    obj1 === obj2  // false
    obj1 == obj2  // false
    

    在声明 obj1 = { name: 'haolucky' } 时,实际上是在堆内存中创建一个对象 { name: 'haolucky' } ,而 obj1 存储的是这个对象在堆内存中的地址,即 obj1 是一个指针,指向了内存中这个对象 { name: 'haolucky' }

    同样的道理,obj2 也是在内存中开辟一个空间,创建了一个对象 { name: 'haolucky' },并指向这个地址。

    综上所述,因为 obj1obj2 是两个不同的地址,所以两者不相等;在 JavaScript 中,引用类型(对象、数组、正则、Date、函数)的比较,实际上是比较指针是否指向存储器中的同一段地址,只有指向同样的地址才能相等。

    对于引用类型,指的是保存在内存中的对象。如果是同一对象,则值相同,不同对象则值不同。

    基本类型参数按值传递
    // 参数都是按值传递的
    var str1 = 1
    var str2 = 2
    function handle(str1, str2){
      str1++
      str2++
      console.log(str1, str2)  // 2, 3
      return str1 + str2
    }
    handle(str1,  str2)
    console.log(str1)  // 1
    console.log(str2)  // 2
    

    上面的函数中的参数是实参的拷贝,并不会影响全局的变量

    引用类型参数按值传递
    function change(obj) {
         obj.age = 16
         obj = new Object()
         obj.age = 18
     }
     var obj = new Object()
     change(obj)
     console.log(obj.age)  // 16
    
    调用 change 函数时,传过去的 obj 参数是实例 new Object() 在内存中的地址,是按值传递,它们指向同一个地址对应的对象。如果改变里面的值,外面的实例也能相应的发生改变。obj = new Object() 重新给 obj 在内存中开辟了一个空间,指向了另外一个对象,所以不能修改外面实例的值。

    1、实参将指向的内存地址传递给形参 ,按值传递的值指的是内存地址;
    2、形参修改了它和实参共同指向的对象后,外部的实参会反映出来;
    3、但形参始终无法修改实参指向的内存地址,即如果将形参指向新的对象,实参并不会指向新的对象。

    使用案例:无返回值的带参void函数是没有返回值的,那么对于传入的参数在计算处理之后,怎么把结果返回呢?软件开发中实际上最常用的两种方式:指针和引用!在主程序中直接声明一个变量,然后把这个变量的引用或者指针作为参数直接传递给void函数,当void函数在做处理时,直接将结果写到引用参数或者指针指向的主函数变量,这样就间接实现了“返回值”。一可以让代码更简洁,二是能减少内存空间的占用。

    在JavaScript中,函数的参数传递方式都是按值传递,没有按引用传递的参数。

    但是JavaScript中有保存引用的对象,比如数组,它们是按引用传递的。
    function curve(arr, amount) {
      for(var i =0; i < arr.length; ++i) {
        arr[i] += amount;
      }
    }
    var grades = [1,2,3,4,5,6]
    curve(grades, 5)
    print(grades);   //  [6, 7, 8, 9, 10]
    

    连续赋值

    var obj1 = {n: 1}
    var obj2 = obj1
    /* obj1.x = obj1
    console.log(obj2, obj1)  // obj2 = {n:1,x:{n:1,x{...}}},obj1 = {n:1,x:{n:1,x{...}}} */
    
    obj1.x = obj1 = {n: 3}
    console.log(obj1, obj2, obj1.x, obj2.x) // {n:3}, {n:1,x:{n:3}}, undefined, {n:3}
    

    obj1obj2 都指向了对象A

    1. .运算符的优先级高于 =
      先计算 obj1.x,并且此处的 obj1 指向是初始对象A
      obj1.x = undefined 对象A此时变成了 {n:1,x:undefined}
      obj1 = {n:1,x:undefined} obj2 = {n:1,x:undefined}

    2. 然后从右至左依次运算
      obj1 = {n:3} 指针发生了改变
      obj1 重新指向一个新的对象B {n:3}
      obj1 = {n:3} 此时 obj2 = {n:1,x:undefined}

    3. obj1.x = obj1 直接赋值,并不会改变指针
      这个 obj1.x 中的 obj1 就是第一步的初始对象A,而后面的obj1在第二步的时候已经重新指向了新对象B
      obj1.x = {n:3}
      相当于 ===> obj2.x = {n:3}
      obj2 = {n:1,x:{n:3}}
      当打印 obj1.x

    相关文章

      网友评论

          本文标题:指针和引用

          本文链接:https://www.haomeiwen.com/subject/nbpcfctx.html