昨天整理了 Array 的相關方法,那今日來聊聊物件~
var myObject = {
name: 'Ryan'
};
console.log(myObject.name); // Ryan
myObject.age = 18;
console.log(myObject.age); // 18
var students = {};
students['Bob'] = {age: 18, sex: "male"};
students['Alice'] = {age: 17, sex: "female"};
console.log(students);
// {
// Bob: {age: 18, sex: "male"},
// Alice: {age: 17, sex: "female"}
// }
要執行函數要加
()
var myObject = {
teacher: 'Ken',
student: ['A', 'B', 'C'],
sayHi: function(){
alert('Hi');
}
};
myObject.sayHi(); // Hi
有寫過其他物件導向語言的應該會覺得很熟悉,
function circle(r){
this.r = r;
this.area = Math.PI * r * r;
this.print = function(){
console.log("radius = " + r);
};
}
var ball = new circle(10);
ball.print(); // "radius = 10"
我們在 Day2 介紹了基本型別(Number、String、Boolean、null、undefined),它們屬於 call by value
。而 Array、Object 為 call by reference(sharing)
。
PS. 關於 call by reference、sharing 的深入討論有興去可以去查查,這邊就直接稱呼 call by reference。
那什麼是 call by value
呢?
可以看看這個範例,
a
和 b
的值存放的記憶體位置不一樣,b
不會影響到 a
。var a = 123;
var b = a;
b = 456;
console.log(a); // 123
console.log(b); // 456
恩...看起來好像沒什麼特別,a
、b
本來就不一樣。
那請再看看這個範例,請問 Q1
、Q2
分別是多少?
var a = {value: 100};
var b = a;
b.value = 500;
console.log(a.value); // Q1=?
console.log(b.value); // Q2=?
想好了嘛,答案是,
Ans:Q1
= 500Q2
= 500
咦,為什麼我改動 b
的值,連帶影響到 a
的值了呢?
這就是 call by reference
,
JS 中的 Array、Object
都屬於這種特性,它們在傳遞時,是傳記憶體地址
;而不是單純傳值
而已。
還是有點抽象嗎,那我再舉一個例子:
「我手上有一張白紙,上面寫了 100,那我再拿一張白紙,上面也寫 100,並把這張白紙送給你。試問,你在你的白紙上面把數字改成 1000,請問我的白紙上面數字會變成 1000 嗎?」
上方的例子是普通的兩個人進行示範,不是在看大衛魔術(X,所以我的白紙不會因為他更改他自己的白紙而影響到我的值。
這個概念就是 call by value
,只有單純的對值做變動。
好了,那我再舉一個例子做說明:
「今天有個小偷A要闖空門偷東西,他手上有一張白紙寫著那間倒楣房子的地址。但是被同行B偷看到了那個地址,並決定下手為強,就先去把房子裡 100 萬的現金搬走,而小偷A晚上照著地址過去要偷東西時,發現房子已經被洗劫一空,當場痛哭失聲」
這只是舉例,請勿做出會讓家人傷心的事情(O,
那這個概念就是 call by reference
,白紙上的地址導向的是那間房子,所以不管有幾張白紙上面都寫了那個地址,它們都是指向同一間房子,所以房子的錢被搬走,其他人來當然看不到那些被偷走的錢了。
回到上方的範例,所以 b = a
,實際上 b 是指到 a 的記憶體位置,所以 a 和 b 指向的是同一個地址,更改 b 的值也會影響到 a 的值。
那再看看這個範例,請問 Q3
會印出 60
還是 100
?
function addNum(tmp){
tmp.grade += 40;
}
var student = {grade: 60};
addNum(student);
console.log(student.grade); // Q3=?
沒錯,答案是,
Ans:Q3
= 100
因為函數傳遞的參數為物件時也是一樣的特性。
明後兩天會聊聊深拷貝、淺拷貝,還有 ES6 對於物件的一些方法。
那今日的分享就到這,我們明天見