JavaScript原型

構造函數建立對象帶來的問題

上一篇文章介紹了JavaScript建立對象的幾種方法,都有各自的優缺點。
構造函數看起來好像很好,可是它也有一個問題,那就是建立出來的每個實例對象的方法都是一個獨立的函數,即便他們的內容是徹底相同的,這是不符合函數的代碼複用原則的,並且也不可以統一的修改已被建立的實例的方法。segmentfault

function Person(name, age, sex) {
        this.name = name;
        this.age  = age;
        this.sex  = sex;
        
        this.introduce = function () {
            console.log("我叫" + this.name + ", 今年" + this.age + "歲.");
        };
    }
    
    var jerry = new Person("Jerry", "21", "M");
    var julia = new Person("Julia", "27", "F");

    console.log(jerry.introduce === julia.introduce);        // false

上述代碼中的jerry對象和julia對象的introduce()方法是兩個獨立的函數,數據不共享,若是對象建立更多就浪費了大量的內存空間。函數

JavaScript原型解決方案

在 JavaScript 中,每當定義一個對象(函數也是對象)時候,對象中都會包含一些預約義的屬性。其中每一個函數對象都有一個 prototype 屬性,這個屬性指向函數的原型對象。this

那麼,這個原型對象有什麼做用呢?
構造函數是一個函數對象,因此就會有一個 prototype 屬性,也就有了一個原型對象,既然這是一個對象,那麼久能夠爲它添加屬性和方法。而這個原型對象做爲這個構造函數的一個屬性,是被其建立出來的全部實例共享的。 prototype

因此上面的代碼咱們能夠這樣改寫code

function Person(name, age, sex) {
        this.name = name;
        this.age  = age;
        this.sex  = sex;
    }

    Person.prototype.introduce = function () {
        console.log("我叫" + this.name + ", 今年" + this.age + "歲.");
    };

    var jerry = new Person("Jerry", "21", "M");
    var julia = new Person("Julia", "27", "F");

    console.log(jerry.introduce === julia.introduce);        // true

這樣就解決了數據共享的問題,達到了代碼複用的目的,不管經過此構造函數建立了多少個對象,introduce 方法只會佔用一分內存空間。
且能夠統一修改全部 Person 構造函數建立的實例對象的 introduce 方法。對象

原型對象中的方法是能夠相互調用的

function Dog(name, age) {
        this.name = name;
        this.age = age;
    }

    Dog.prototype.play = function () {
        console.log("小狗玩耍");
        this.bark();
    };

    Dog.prototype.bark = function () {
        console.log("小狗叫");
    };

    var tom = new Dog("Tom", 3);
    
    tom.play();// 小狗玩耍    小狗叫
相關文章
相關標籤/搜索