-_-#【传值 / 传址】
var o1 = {} var o2 = o1 o2.a = 'a' // o2和o1指向相同 console.log(o1, o2) o2 = {b: 'b'} // o2指向新的 console.log(o1, o2)
var a = 10, // 基本数据类型 b = a, // 将变量a保存的值复制一份,传给变量b,a和b各保存一份数据 c = [1, 2, 3], // 复杂数据类型 d = c; // 将变量c指向的数据的内存地址传给变量d,c和d指向同一份数据 b++; d.push(4); console.log(a); // 10 console.log(b); // 11 变量b保存的数据更改不会影响到变量a console.log(c); // [1,2,3,4] 变量c和d指向同一份数据,数据更改会互相影响 console.log(d); // [1,2,3,4] /* 赋值语句会用传值和传址两种不同的方式进行赋值,如果是数值型、布尔型、字符型等基本数据类型,在进行赋值时会将数据复制一份,将复制的数据进行赋值,也就是通常所说的传值,如果是数组、hash对象等复杂数据类型(数组、hash对象可包括简单类型数据),在进行赋值时会直接用内存地址赋值,而不是将数据复制一份,用复制的数据进行赋值,也就是通常所说的传址。 */
console.log([] == []) // false console.log({} == {}) // false console.log(1 === 1) // true
var a = [1, 2, 3], b = {name: 'adang', sex: 'male', tel: '1234567'}, c = [], d = {}; for (var p in a) { c[p] = a[p]; } for (var p in b) { d[p] = b[p]; } c.pop(); d.email = 'xxx@gmail.com'; console.log(a); // 1,2,3 console.log(c); // 1,2 console.log(b.email); // undefined console.log(d.email); // xxx@gmail.com /* 在原生javascript中,选择传值还是传址是根据数据类型自动判定的,但传址有时候会给我们带来意想不到的麻烦,所以我们需要对复杂类型的赋值进行控制,让复杂类型也可以进行传值。最简单的做法是遍历数组或hash对象,将数组或hash对象这种复杂的数据拆分成一个个简单数据,然后分别赋值 */ // 对于数组的传值还可以使用数组类的slice或concat方法实现 var e = [7, 8, 9], f = e.slice(), // slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。 g = e.concat(); // concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。 f.pop(); g.push(10); console.log(e); // 7,8,9 console.log(f); // 7,8 console.log(g); // 7,8,9,10
function change(Obj) { Obj.name = 'first' console.log(Obj, a) Obj = new Object() Obj.name = 'second' console.log(Obj, a) } var a = new Object() change(a) //console.log(Obj) // Obj is not defined console.log(a.name) // first