上一篇文章介紹了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 中,每當定義一個對象(函數也是對象)時候,對象中都會包含一些預約義的屬性。其中每一個函數對象
都有一個 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();// 小狗玩耍 小狗叫