iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
0
自我挑戰組

邁向 JavaScript 核心之路 系列 第 16

[Day 16] JavaScript 物件導向- 原型鏈 ( prototype chain )

  • 分享至 

  • xImage
  •  

各位朋友打給後,看完前面幾個章節後,不知道各位有沒有理解呢?

如果還是似懂非懂的話,沒關係哦,今天在介紹原型鏈之前,

先來說一個小故事吧!

很久很久以前,早在六大派圍攻光明頂之前,有一位小和尚每天努力砍柴挑水,有一位高人見他骨骼驚奇,是萬中選一的練武奇才,於是就帶他上山學藝去,若干年後,小和尚學藝有成,下山行俠仗義,恰巧有一天遇到一個十惡不赦的魔頭,他施展其一身武藝,但魔頭也是極為難纏,且師門好像沒有教過破解的方法,於是小和尚情急之下,變仰天大喊,祖師爺救命,說時遲,那時快,一道白光罩頂,祖師爺降駕於小和尚身上,一套套絕世武功施展了出來,但似乎效果不彰,這時小和尚心裡著急,就催促的祖師爺使出那道從天而降的掌法來降敵,但不巧的是,祖師爺的並不會如來神掌,於是乎,祖師爺便與小和尚說,你先撐著,我也去找我的祖師爺來問問...

你可能會很疑問,哩系勒公三小,孩子,剛剛這串故事,我們已經把原型鏈講完了。

小和尚 ( object )
上山學藝 ( new function someone )
找不到破解方法 ( object 沒有某某方法 )
祖師爺附體 ( __ proto __ )
效果不彰 ( __ proto __ 沒有某某方法 )
祖師爺的祖師爺 ( 繼續往原型的原型去找)

有了原型鏈的概念,下面我們就來講點正經的吧 XDDD

我們先來定義幾個概念

  1. 在 JavaScript 當中,萬物都是物件,Function 是物件,方法的原型 ( Function.prototype ) 也是物件,也因此他們共有物件的特性。

物件都有一個屬性叫 __ proto __,每個物件的 __ proto __ 指向建構這個物件的函式的原型,這就保證了物件能夠使用到建構函式中定義的屬性與方法。

  1. Function是個特殊的物件,它除了有 __ proto __ 這個屬性之外,他還有自己特有的屬性,Prototype,這個屬性指向一個對象,這個對象的用途就是包含所以共用的方法與屬性,我們稱呼它叫原型,而原型它也有一個屬性,叫做 constructor,這個屬性同樣包含了一個指針,指向原建構函式。

是不是覺得有點繞口又難懂,沒關係,現在來看看日常會怎麼用 prototype 吧!

    function CreatePerson(name, gender) { // 通常建構函式字首會是大寫,這是命名規則的習慣
        this.name = name;
        this.gender = gender;
    }
    
    CreatePerson.prototype.showName = function() {
        console.log("my name : " + this.name);
    }
    
    CreatePerson.prototype.showGender = function() {
        console.log("my gender : " + this.gender);
    }
    
    var p1 = new CreatePerson("Reynold", "male");
    var p2 = new CreatePerson("Cher", "female");
    
    console.log( p1.showName === p2.showName ) // true;

上面的程式碼,我們快速地產生了兩個物件,並讓他們共用了 showName 和 showGender 方法,這達到了我們節省系統資源的目的,避免重複產生方法。

是不是不太過癮,沒關係,我們再來一個

    function Obj() {
        this.name = "Mark";
        this.run = function() {
            console.log("run");
        }
    }
    
    var a = new Obj();
    var b = new Obj();
    var c = new Obj();
    
    // 這時候如果要幫每個物件增加同樣屬性,一般人可能會這樣做
    
    a.height = 15;
    b.height = 15;
    c.height = 15;
    
    // 但聰明的你一定會想到
    
    Obj.prototype.height = 15;
    

因為 Obj.prototype === a.__ Proto __ ,所以你新增 Obj.prototype.height 屬性等同於 a.__ Proto __.height,而當 a 物件在自己本身找不到 height 屬性,就會去 __ proto __ 底下尋找 height,若在找不到,就會在往上層的 __ proto __去尋找,一直找到 null 為止。

當然,我們也可以替系統內建的物件用原型來加方法,來達到擴充功能的目的。


    String.prototype.toNumber = function() {
        return parseInt(this);
    };
    
    var ten = "10";
    
    console.log(ten.toNumber()); // 10
    console.log(typeof (ten.toNumber())); number
    

最後補充個小知識,原型鏈找到最後會是 null


不知道大家看不看得懂我的小劇場 XDDDD,突然腦洞大開想用這樣的方式呈現,讀者給我一點回饋 RRR

參考資料:

Tommy - 深入 JavaScript 核心課程
每日頭條 - Javascript 原型鏈和原型繼承


上一篇
[Day 15] JavaScript 物件導向- new 與 prototype
下一篇
[Day 17] JavaScript 物件導向- 私有函式與變數、唯獨方法和屬性
系列文
邁向 JavaScript 核心之路 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言