Javascript prototype and this記憶體用量

在javascript中,使用function建立一個object時,用prototype來配置屬性,被建立的object會指向同一個prototype object,而使用this建立的,則會是獨立的屬性

Example:

定義TomMary二個人。

1
2
3
4
5
6
7
function Tom(){

}

function Mary(){

}

使用prototype定義John的父母,分別為TomMary

1
2
3
4
5
6
John.prototype = {
parents:{
dad:new Tom(),
mom:new Mary()
}
};

this的方式定義John的父母。

1
2
3
4
5
6
7
function John(){

this.parents = {
dad:new Tom(),
mom:new Mary()
};
}

然後用thisprototype的方式,各自建立1000000

1
2
3
4
5
var people = [];

for( var i = 0; i < 1000000 ; i++ ){
people.push( new John() );
}

結果如下:

使用prototype的方式
使用this的方式

this使用的記憶體為72.5m,而prototype的記憶體是25m,由此可知,使用prototype來建立多個object,會節省很多記憶體。


完整Prototype Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>use "prototype"</h1>
<button id="create">create children</button>
<div id="count">0</div>

<script type="text/javascript">
function Tom(){

}

function Mary(){

}

function John(){

}

John.prototype = {
parents:{
dad:new Tom(),
mom:new Mary()
}
};

var people = [],countElem = document.querySelector("#count");

document.querySelector("#create").addEventListener( "click", function(){

for( var i = 0; i < 1000000 ; i++ ){
people.push( new John() );
}

countElem.innerHTML = people.length;
});

</script>
</body>
</html>

完整This Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>use "this"</h1>
<button id="create">create children</button>
<div id="count">0</div>

<script type="text/javascript">

//define dad
function Tom(){

}

//define mom
function Mary(){

}

//define child
function John(){

this.parents = {
dad:new Tom(),
mom:new Mary()
};
}


var people = [],countElem = document.querySelector("#count");

//create children
document.querySelector("#create").addEventListener( "click", function(){

for( var i = 0; i < 1000000 ; i++ ){
people.push( new John() );
}

countElem.innerHTML = people.length;
});

</script>
</body>
</html>

Javascript Prototype的概念

javascript的prototypethis,是剛接觸javascript的人比較難理解的。在javascript裡,假設定義一個一個Bird function時,可使用同個prototype建立不同物件,也就所有經由Bird function產生的物件,都會擁有相同的protoype的屬性。

Example:

定義一隻鳥,這種鳥的名稱叫做Sparrow

1
2
3
4
5
6
7
function Bird(){
//do something
}

Bird.prototype = {
name:"Sparrow"
};

接著建立兩個變數,分別為Tom的寵物

1
2
var bird = new Bird();
var petOfTom = new Bird();

Tom把他的寵物稱為Raven,而這種的名稱,重新命名為Black Sparrow

1
2
3
petOfTom.name = "Raven";

Bird.prototype.name = "Black Sparrow";

最後你就會發現一個有趣現象,即使這種的名稱重新命名了,Tom的寵物仍然會以Tom命名的方式顯示

1
2
3
4
5
//name of bird:Black Sparrow 
console.log( "name of bird:" + bird.name );

//Tom's pet called him: Raven.
console.log( "Tom's pet called him: " + petOfTom.name + "." );

也就是說也就是說,當prototype的name改變時,其他經由Bird new出來的object name,都會跟著修改但是被new出來的object,一旦屬性被修改,不管之後prototype如何更動,則object的屬性會依照你所指定的修改


完整範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>

<script type="text/javascript">

function Bird(){

}

Bird.prototype = {
name:"Sparrow"
};

var bird = new Bird();
var petOfTom = new Bird();

console.log( "name of bird:" + bird.name );

//rename
petOfTom.name = "Raven";

//rename
Bird.prototype.name = "Black Sparrow";

console.log( "rename..." );

console.log( "name of bird:" + bird.name );

console.log( "Tom's pet called him: " + petOfTom.name + "." );

</script>

</body>
</html>