iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 15
0
自我挑戰組

邁向 JavaScript 核心之路 系列 第 15

[Day 15] JavaScript 物件導向- new 與 prototype

  • 分享至 

  • xImage
  •  

嗨,各位朋友打給後

昨天提到的建立物件最後我們有帶出兩大問題點,今天我們就要來解決這些問題。

就先讓我們來介紹一下 new 吧!

當我們在編輯器上輸入 new 一個物件後,它背後會幫你做些什麼呢?

  1. 會先創建一個空的物件,也就是大家熟悉的 {} 。
  2. 連接該物件( 也就是我們所 new 的對象 ) 到剛剛創建的物件。
  3. 然後將步驟一創建出來的物件作為 this。

所以我們可以這樣說 new 的原理其實就是藉由類別來產生出物件,但由於 JavaScript 沒有 class,所以我們藉由 function 來當作 class。


    // 使用 new 與不使用的差異
    
    function showThis() {
        console.log( this );
    }
    
    showThis();// Window,也就是所謂的全域
    new showThis();// 會返回一個物件
    

接下來,我們就用一段程式碼來示範日常用 new 產生物件的情境吧


    function CreatePerson(name, gender) { // 建構一個物件的函式 ( 設計圖 )
        // 系統內部執行
        // var this = new Object();
    
        this.name = name;
        this.gender = gender;
        this.showName = function() {
            console.log("my name : " + this.name);
        };
        this.showGender = function() {
            console.log("my gender : " + this.gender);
        };
    
        //系統內部執行
        // return this;
    }
    
    var p1 = new CreatePerson("Reynold", "male");
    var p2 = new CreatePerson("Cher", "female");
    

如果有 return 的話會以 return 的東西為主。

目前我們解決了昨天提到的第一個問題點 沒有使用 new
現在要來解決第二個問題點 每次建立一個新的物件,就產生了一個新的方法,造成記憶體資源上的浪費

那該如何解決呢?

答案是 prototype

原型( prototype ) 可以解決建立物件時,重複產生方法的問題。

只有在類別上面才可以建立原型方法,在物件上無法建立。

下面我們就用程式碼來示範,透過原型加上方法,使所有的物件都可以操作。


    var ary1 = new Array(1, 2, 3, 4, 5);
    var ary2 = new Array(1, 3, 5);
    
    Array.prototype.sum = function() {
        var output = 0;
        for ( var i = 0; i < this.length; i ++ ) {
            output += this[i];
        }
        return output;
    };
    
    console.log(ary1.sum());
    console.log(ary2.sum());
    

屬性不存在的話,取值會 undefined,方法不存在的話,執行會 exception。

如果對 pototype 還不是很懂的朋友,這邊打個比喻,假設我們今天站內的標題都是統一樣式,那我們就會針對標題來撰寫一個 class,所以未來只要看到是標題的元素,加上該 class 後就能直接套上樣式了,pototype 就有點類似這樣的概念,只是套上樣式的方法變成 new 。

    .title {
        font-size: 28px;
        font-weight: bold;
    }

如果我們透過原形加方法,但物件上也有自己的方法( 兩個方法同名的狀況 ),這時,會以物件自己的方法為優先。

    
    var ary1 = new Array(1, 2, 3, 4, 5);
    var ary2 = new Array(1, 3, 5);
    
    Array.prototype.sum = function() {
        var output = 0;
        for ( var i = 0; i < this.length; i ++ ) {
            output += this[i];
        }
        return output;
    };
    
    ary1.sum = function() {
        return "nothing";
    };
    
    console.log(ary1.sum()); // nothing
    console.log(ary2.sum()); // 9
    

這樣我們就解決了每次建立一個新的物件,就產生了一個新的方法,進而造成記憶體資源上的浪費的這個問題。


賺到一天颱風假,有充分的時間來思考、撰寫,感覺真是舒暢。

參考資料:

Tommy - 深入 JavaScript 核心課程
MDN - new 運算符


上一篇
[Day 14] JavaScript 物件導向- 建立物件
下一篇
[Day 16] JavaScript 物件導向- 原型鏈 ( prototype chain )
系列文
邁向 JavaScript 核心之路 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言