[JS奇怪的世界]No.51 函數建構子與「.prototype」

前言

我們已經知道函數建構子可以幫助新物件設定屬性及方法,但原型呢?所以接下來就要來做講檢該如何設定原型。

prototype

這是上一章節的範例

1
2
3
4
5
6
7
8
function Person(first, last) {
this.firstname = first;
this.lastname = last;
}

var john = new Person('John', 'Doe');

console.log(john);

當我們使用函數建構子的時候,就已經被 JavaScript 給準備好了,所以我們可以試著輸入 john.__proto__

我們會得到一個物件,不信?我收合給你看。

那這個物件是什麼?我們先前有講過函數就是物件,在 JavaScript 函數就是物件,然後所有物件都有原型屬性 (prototype property),但是一般來講我們並不會用到,他只是掛在那裏而已。

除非我們將函數作為函數建構子來使用。

讓我們來試試看。

1
2
3
4
5
6
7
8
9
10
11
12
function Person(first, last) {
this.firstname = first;
this.lastname = last;
}

Person.prototype.getFullName = function() {
return this.firstname + ' ' + this.lastname;
}

var john = new Person('John', 'Doe');

console.log(john);

我們可以看到我們可以原型下有了 getFullName(),換一個角度來看。

所以我們可以知道,當然函數被當作函數建構子使用時,就會有原型,那為什麼我們要將 getFullName 放進原型內?我們也可以直接放在函數建構子內?

1
2
3
4
5
6
7
8
9
10
11
function Person(first, last) {
this.firstname = first;
this.lastname = last;
this.getFullName = function() {
return this.firstname + ' ' + this.lastname;
}
}

var john = new Person('John', 'Doe');

console.log(john);

假設今天有一千種物件都放在 getFullName 內,就會佔據比較多的記憶體,但若放在原型上就會比較好。

以效能來講將重複的屬性與方法放在原型上會比較好,因為這樣做我們就不用每一次都在 Person 裡面加入物件,只需要將重複需要使用的放在原型,然後透過原型去取得使用就好了。

所以就可以這樣寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Person(first, last) {
this.firstname = first;
this.lastname = last;
}

Person.prototype.getFullName = function() {
return this.firstname + ' ' + this.lastname;
}

Person.prototype.getFormaFullName = function() {
return this.firstname + ', ' + this.lastname;
}

var john = new Person('John', 'Doe');
console.log(john);

var jack = new Person('John', 'Doe');
console.log(jack);

這樣兩者皆可以使用。

圖源

JavaScript 全攻略:克服 JS 奇怪的部分