1. 程式人生 > >A1—淺談JavaScript中的原型(二)

A1—淺談JavaScript中的原型(二)

js

原型是什麽?想要了解這個問題,我們就必須要知道對象。

對象

根據w3cschool上的介紹:對象只是帶有屬性和方法的特殊數據類型。

我們知道,數組是用來描述數據的。其實呢,對象也是用來描述數據的。只不過有一點點的區別,那就是數組的下標只能是數字。所以,數組最好只用來裝同樣意義的內容。比如說[1,2,3,4,5]或者[“a”,”b”,”c”,”d”,”e”]等。因為他們的表達的含義是一樣的。那麽如何表達含義不一樣的內容呢?[“小明”,12,”男”]這樣的內容。鬼知道它要表達什麽啊!所以,由於數組的下標只能是數字。無法準確的表達每一項的含義。於是乎,對象出現了。

對象=> { “name”:”小明”,”age”:12,”sex”:”男”}。對象就是由各種key:value對組成的數據結構。

看,數組[“小明”,12,”男”]與對象{ “name”:”小明”,”age”:12,”sex”:”男”}都有相同的值。只不過對象表達的更清晰。更能讓人知道每一個數據表達的含義是什麽!

我們上面的對象,很明顯的想要描述一個人的各項信息。那麽能不能描述一下這個人能做的事情呢?比如說:“唱歌”“讀書”。

當然可以!

{

“name”:”小明”,

”age”:12,

”sex”:”男”,

”sing”:function{

console.log(“我在唱歌”);

},

”read”:function{

console.log(“我在讀書”);

}

}看,通過上面這樣一組一組的key:value對就能夠清晰的表達一個人的各項屬性和方法

屬性:對象的key對應的東西都叫做屬性。方法:(接上句)但是,如果這個key對應的是一個函數,那麽我們叫它方法。

好了,現在我們知道什麽叫對象以及對象可以擁有方法。那麽在JavaScript中我們想要創建多個相似的對象該怎麽辦呢?很明顯,我們不是一條一條寫出來的。

我們知道,在JavaScript中,函數的作用是復用代碼。而定義一個對象其實就是一條條代碼組成的。那麽我們可以這樣寫。

function createPeople{

var obj = {

“name”:”小明”,

”age”:12,

”sex”:”男”,

”sing”:function{

console.log(“我在唱歌”);

},

”read”:function{

console.log(“我在讀書”);

}

}

}

看,我們使用函數來簡化了代碼的書寫。這樣每當我們調用一次函數就能夠創建一個“小明”出來。可是我們如果創建的對象的屬性值不一樣,該怎麽辦呢?

思考:簡單,函數不是可以傳遞參數嗎?

我先把函數內部的對象的所有屬性都定義成形參。然後當函數調用的時候傳遞實參就可以了呀!

代碼如下:

function createPeople(name,age,sex){

var obj = {

“name”:name,

”age”:age,

”sex”:sex,

”sing”:function{

console.log(“我在唱歌”);

},

”read”:function{

console.log(“我在讀書”);

}

}

}

現在好了,我們每執行一次函數並傳遞不同的參數,就可以獲得到不同的對象了。

createPeople(“小明”,12,”男”);=>得到一個小明對象

createPeople(“小紅”,12,”女”);=>得到一個小紅對象

但是!!!!!!!!

發現沒有?????

每調用一次createPeople函數,我們就會定義兩個新的函數:sing和read。並且定義完畢之後會被這個對象的屬性引用。那麽這樣的話我們創建了小明和小紅,就會在內存中開辟4個地址。

分別存放小紅.sing、小紅.read、小明.sing、小明.read。

而小紅.sing和小明.sing的功能是一模一樣的。小紅.read和小明.read方法也是一模一樣的。這不科學!!!!!!

現在我們只是調用了兩次createPeople,就會創建四個新的函數。那麽如果調用二十次呢?如果每個對象不僅僅只有兩個方法呢?

我們知道函數的使命就是讓代碼被復用。可是,卻出現了每一個對象都有一個自己的方法這種情況。這樣將會造成內存的極大浪費!

也就是說:

小明.sing===小紅.sing的結果為false

那我們就想:要是能提取出來就好啦!

當然可以!

function createPeople(name,age,sex){

var obj = {

“name”:name,

”age”:age,

”sex”:sex,

”sing”:sing,

”read”:read

}

}

function sing{

console.log(“我在唱歌”);

}

function read{

console.log(“我在讀書”);

}

發現沒有?我們成功的將所有的對象的方法,都提取出來了,這樣不管創建多少對象。都僅僅會在內存中有一個地址。也即是說

createPeople(“小明”,12,”男”);=>得到一個小明對象

createPeople(“小紅”,12,”女”);=>得到一個小紅對象

此時:小紅.sing ===小明.sing結果為true

但是,如果方法一旦多了,就會在全局作用域下造成汙染。全局作用域中會出現好多的變量。所以再進一步簡化:

function createPeople(name,age,sex){

var obj = {

“name”:name,

”age”:age,

”sex”:sex,

”sing”:peopleMethod .sing,

”read”:peopleMethod .read

}

}

var peopleMethod = {

sing: function {

console.log(“我在唱歌”);

},

read:function {

console.log(“我在讀書”);

}

}

好了,現在不怕汙染全局作用域了。(雖然還是會有一個全局變量,但是已經比之前好多了不是嗎)

那麽,根據這個原理,小明調用的sing方法,其實是peopleMethod的sing方法。

小紅調用的sing方法其實也是peopleMethod的sing方法。

這樣的話我們可以說小明和小紅的方法都是peopleMethod的。

那也就可以說,

peopleMethod是小明和小紅的方法對象。

而JavaScript就在設計之初,將這個對象放在了構造函數上。

這樣從構造函數構造出來的對象,就會共享原型上的方法。


本文出自 “青蛙” 博客,轉載請與作者聯系!

A1—淺談JavaScript中的原型(二)