# 隱藏諸多細節的建構式

``````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]
``````

`Person` 這樣的函式，接在 `new` 之後使用時，俗稱為建構式（Constructor），通常對從類別為基礎的語言過來的人，也會說這就像是一個類別（Class），不過這只是比擬，實際上與它並不是類別。

``````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
``````

`instanceof` 可用來測試物件是否由經由某個建構式 `new` 出來，由於實際上 `Person` 中定義了 `return []``new Person()` 傳回的是 `[]`，因此 `instanceof` 測試結果並不是 `Person` 建構的實例。

``````function Person() {}
var p = new Person();
console.log(p.constructor === Person);                  // true
console.log(Person.prototype.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
``````

``````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
``````

``````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
``````