JavaScript 語言核心(14)隱藏諸多細節的建構式
|
JavaScript 語言核心(13)在 Scope chain 查找變數 << 前情 如果你有以下建立物件的需求: function toString() {
return '[' + this.name + ',' + this.age + ']';
}
var p1 = {
name : 'Justin',
age : 35,
toString : toString
};
var p2 = {
name : 'Monica',
age : 32,
toString : toString
};
var p3 = {
name : 'Irene',
age : 2,
toString : toString
};
console.log(p1.toString()); // [Justin,35]
console.log(p2.toString()); // [Monica,32]
console.log(p3.toString()); // [Irene,2]
這些物件在建立時,具有相同的特性名稱,只不過特性值不同,其實你如下定義 function toString() {
return '[' + this.name + ',' + this.age + ']';
}
function Person(name, age) {
this.name = name;
this.age = age;
this.toString = toString;
}
var p1 = new Person('Justin', 35);
var p2 = new Person('Monica', 32);
var p3 = new Person('Irene', 2);
接著如下呼叫 var p1 = new Person('Justin', 35);
var p2 = new Person('Monica', 32);
var p3 = new Person('Irene', 2);
console.log(p1.toString()); // [Justin,35]
console.log(p2.toString()); // [Monica,32]
console.log(p3.toString()); // [Irene,2]
像 實際上使用 function toString() {
return '[' + this.name + ',' + this.age + ']';
}
function Person(name, age) {
this.name = name;
this.age = age;
this.toString = toString;
}
var p = {};
Person.call(p, 'Justin', 35);
console.log(p.toString()); // [Justin,35]
這也說明了,為什麼使用 說是一部份作了這些動作,不過還有別的細節,像是原型繼承以及 function toString() {
return '[' + this.name + ',' + this.age + ']';
}
function person(name, age) {
return {
name : name,
age : age,
toString : toString
};
}
var p = person('Justin', 35);
console.log(p.toString()); // [Justin,35]
原型繼承會在另一篇文章中說明,稍後則就會看到 一個函式作為建構式使用時,基本上無需撰寫 function Nobody() {
}
function Person(name, age) {
return [];
}
var n = new Nobody();
var p = new Person();
console.log(n instanceof Nobody); // true
console.log(p instanceof Person); // false
console.log(p instanceof Array); // true
每個透過 function Person() {}
var p = new Person();
console.log(p.constructor == Person); // true
雖然這可以作為判斷物件類型的參考依據之一,不過要注意的是, 由於透過建構式所建立的物件,所有的特性都是直接新增在物件上,也因此可以直接透過 . 運算子加以存取。例如: function Person(name, age) {
this.name = name;
this.age = age;
}
var p = new Person('Justin', 35);
console.log(p.name); // Justin
console.log(p.age); // 35
對熟悉物件導向私有(private)特性的人來說,可能覺得這不安全,這相當於在物件導向觀念中,每個類別成員都是公開成員的意味。JavaScript 本身並沒有支援物件導向私用特性的語法,如果你想模擬,則可以如下: function Person(name, age) {
this.getName = function() {
return name;
};
this.age = age;
}
var p = new Person('Justin', 35);
console.log(p.name); // undefined
console.log(p.getName()); // Justin
console.log(p.age); // 35
以上假設的是, 由於 Closure 綁定的是變數本身,所以也可以如下,在設定值(或取得值)時予以保護: function Account() {
var balance = 0;
this.getBalance = function() {
return balance;
};
this.setBalance = function(money) {
if(money < 0) {
throw new Error('can\'t set negative balance.');
}
balance = money;
};
}
var acct = new Account();
console.log(acct.getBalance()); // 0
acct.setBalance(1000);
console.log(acct.getBalance()); // 1000
acct.setBalance(-1000); // Error: can't set negative balance
建構式還有一些細節需要瞭解,這會在下一篇文章中繼續討論。 |

Java 學習之路




