JS形参和函数内部变量重名的问题


   function a(obj) {
      obj.a = 2;
      obj = {
        a: 3
      };
    }
    var obj = {
      a: 1
    };
    a(obj);
    console.log(obj);

第一个obj.a操作的是参数 第二个obj={a:3} 操作的是内部变量 不知道是根据什么来决定操作的是内部变量还是参数

这个是基本变量和引用变量;还有就是传入函数形参的处理问题

  1. 执行a函数出入的obj是引用变量,这个时候传入的是一个地址
  2. a函数内部执行,创建一个obj变量,保存传入的引用变量地址
  3. 改变引用地址里的a属性为2,所以全局的obj也指向这个地址,所以跟着改变为2
  4. 改变a函数变量obj的指向地址为一个新的对象,此处注意没有修改传入形参的地址里的属性,而是直接修改了替换了这个地址
  5. 此时a函数的obj就指向{a:3},全局obj就指向{a:2}
  6. 最后执行console.log(obj);输出全局obj,就是{a:2}

变更的都是 obj

   function a(obj) {
      // 举例传进来的是一个内存地址,变更 内存地址的值 也就是对应的 {a:2} 已经变成
      obj.a = 2;
      // 这个时候直等赋值相当于和传进来的内存地址已经不在指向同一个内存地址,所以不会变更外部的obj 
      obj = {
        a: 3
      };
    }
    // 外部声明的obj 指向一个内存地址
    var obj = {
      a: 1
    };
    // 将指向的内存地址传给 函数参数,函数参数就是对应的数据
    a(obj);
    // 执行后 输出obj ={a:2}
    console.log(obj);

都是obj 你打印一下

function a(obj) {
    obj.a = 2;
    console.log(obj)
    obj = {
      a: 3
    };
    console.log(obj)
  }
  var obj = {
    a: 1
  };
  a(obj);
  console.log(obj);

要理解程序实质上最终操作的是内存,不是某个名字的参数。
也可以再学习一下函数形参的概念,理解参数和对象实例的差异。程序分析如下:

在内存中创建一个对象实例,obj参数指向这个实例。
var obj = {
a: 1
};

通过参数把对象实例传递给函数去执行。
a(obj);

函数内部的obj参数开始也指向之前创建的对象实例,修改obj.a的值会导致内存中,外部创建的实例值改变。
但内部的obj和外部的obj其实是作用域不同的两个参数,只不过名字相同而已。
obj.a = 2;

创建新的对象实例,让函数内部的obj参数指向这个新的实例,对外部最开始创建的实例没有任何影响,对外部的obj参数也没有任何影响
obj = {
a: 3
};

打印函数外部创建的对象实例,结果是2
console.log(obj);