簡介
值(基本)類型變量,引用類型變量
值類型變量 存在內存的堆中,ex:a=1,
引用類型變量 1.指針存在於棧中,2.引用類型的具體內容存在於堆中 ex:let a={b:1} a的指針指向 堆中的地址0xffac0ec
引用類型
let obja = {};
let objb = null;
objb = obja;
obja = objb;
obja.a = "a";
//引用類型 指向 同一個堆的區域
console.log(obja);
console.log(objb);
console:
{ a: 'a' }
{ a: 'a' }
值類型
let a = 1;
let b = a;
a += 1;
//值類型 兩個單獨的堆空間
console.log(a);
console.log(b);
console
2
1
引用類型 非null
let mm = { a: 1 };
let gg = mm;
mm.a = 2;
console.log(gg);
console.log(mm);
console
{ a: 2 }
{ a: 2 }
引用類型 多次改變堆內容
let cao = new String("aaa");
cao.aa = "123";
let wocao = cao;
cao.aa = "321";
console.log(cao);
console.log(wocao);
[String: 'aaa'] { aa: '321' }
[String: 'aaa'] { aa: '321' }
然而 (逐漸失去耐心…)
引用類型轉換爲值類型 會發生什麼?
let cao1 = new String("aaa");
let wocao1 = cao1;
cao1 = "bbb";
//當cao1 變爲基本類型時,相當於在內存中有一個新的堆空間,cao1的內存地址指向自己本身堆的地址
console.log(cao1); //cao1變爲基本類型了
console.log(wocao1);
//然而wocao1依然是對象類型 而wocao1不受cao1的改變而改變,依然是通過棧的指針 指向new String('aaa')對象的內存地址
console
bbb
[String: 'aaa']
值類型和引用類型 校驗
var yiifaa = "yiifaa",
str1 = new String(yiifaa),
str2 = String(yiifaa);
// 類型爲string,爲值類型
console.log(yiifaa);
console.log("yiffaa " + yiifaa + " " + typeof yiifaa); //string
// 類型爲object,爲引用類型
console.log("str1 " + str1 + " " + typeof str1); //object
// 類型爲string,爲值類型
console.log("str2 " + str2 + " " + typeof str2); //string
console
yiffaa yiifaa string
str1 yiifaa object
str2 yiifaa string
//注意 new String()聲明的是引用類型對象,String聲明的是值對象
值傳遞 引用傳遞 針對的是方法
值傳遞
function addOne(num) {
num += 1;
return num;
}
var count = 10;
var result = addOne(count);
console.log(count);
console.log(result);
//調用addOne(num) 參數num相當於 在方法中拷貝了一個新的num值在堆中,方法內的改變,不會影響到外部變量
10
11
引用傳遞
let objj = { a: 1 };
function objAdd(obj) {
obj.b = 1;
}
objAdd(objj);
//引用傳遞,相當於傳遞的是obj的指針,會影響外部變量 堆中的值
console.log(objj);
{ a: 1, b: 1 }
var person = new Object();
var obj = person; // 賦值
obj.name = "ABC";
obj = new Object(); // 指向 新的對象
obj.name = "BCD";
console.log(person.name); // 指向老的對象 不受影響
console.log(obj.name); // 指向新的對象
console
ABC
BCD