[JavaScriptWeird]No.45 函式建構子與「.prototype」

前言

上一篇看到了函式建構子能夠幫新物件設定屬性和方法,接下來要介紹如何使用函式建構子設定原型,是另一個 JavaScript 建立物件的重要部分。

延續上一篇的程式碼,如下:

1
2
3
4
5
6
7
8
9
function person(firstName, lastName){  
this.firstName = firstName;
this.lastName = lastName;
}
var john = new person('Doe', 'john');
var joan = new person('Mar', 'joan');

console.log(john);
console.log(joan);

問題是,應該要如何設定原型呢?首先觀察一下 johnjoan__proto__ 指向哪邊。

當使用函式建構子時,函式建構子已經幫我們設定好原型了。

建立函式物件時有個特殊屬性像是名稱屬性、程式屬性,還有每個函式都具有的原型屬性 (prototype property),除非將函式做為函式建構子使用,否則原型屬性永遠不會用到,使用 new 運算子並且使用函式建構子來建立物件時,原型屬性才有作用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function person(firstName, lastName){  
this.firstName = firstName;
this.lastName = lastName;
}

person.prototype.getFullName = function(){
return this.firstName + ' ' + this.lastName;
}

var john = new person('Doe', 'john');
var joan = new person('Mar', 'joan');

console.log(john);
console.log(joan);

「.prototype」指的是函式的原型屬性,所謂函式的原型屬性其實就是用函式建構子建立的物件其原型鏈指向的東西。

也就是說 johnjoan 都指向 person.prototype 為原型,它們都可以取用到我增加的 getFullName 方法,甚至可以直接在瀏覽器直接使用。

也可以之後又新增更多東西到原型,像是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function person(firstName, lastName){  
this.firstName = firstName;
this.lastName = lastName;
}

person.prototype.getFullName = function(){
return this.firstName + ' ' + this.lastName;
}

var john = new person('Doe', 'john');
var joan = new person('Mar', 'joan');
console.log(john);
console.log(joan);
person.prototype.getFormalFullName = function(){
return this.firstName;
}
console.log(john.getFormalFullName);

後面才新增在原型上的方法,仍然可以被先前就建立好的物件取用。

這代表之後所有使用 preson 函式建立的物件,都可以取用我們新增在原型上的方法,藉由「.prototype」這個函式的原型屬性。

如果把 getFullName 方法放到 person 函式內,與把 getFullName 方法放到 person 函式的原型屬性內差別在哪?

1
2
3
4
5
6
7
function person(firstName, lastName){  
this.firstName = firstName;
this.lastName = lastName;
this.getFullName = function(){
return this.firstName + ' ' + this.lastName;
}
}

舉例來說,假如前者有一千個物件,那麼這一千個物件內都會新增 getFullName 方法,表示每個物件都會有自己的 getFullName 方法,這會佔據較多的記憶體空間。

而後者的話,雖然有一千個物件,但只會有一個 getFullName 方法,因為這個方法被增加到原型上。

以效能的觀點來看,將重複的屬性和方法放在原型上會比較好。

0%