摘要:組合使用構造函數模式和原型模式構造函數模式用于定義實例屬性,原型模式用于定義方法和共享的屬性。創建對象組合使用構造函數模式和原型模式指向構造函數,這里要將其恢復為指向構造函數。另外,這種混合模式,還支持向構造函數傳遞參數。
組合使用構造函數模式和原型模式
構造函數模式用于定義實例屬性,原型模式用于定義方法和共享的屬性。
創建自定義類型的最常見方式,就是組合使用構造函數模式和原型模式。
1.創建對象// 組合使用構造函數模式和原型模式 function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friend = ["Jenny", "Court"]; } Person.prototype = { constructor: Person, //constructor指向Object構造函數,這里要將其constructor恢復為指向Person構造函數。 Country: "China", showName: function(){ console.log("name = " + this.name); } } var p1 = new Person("Mike", 20, "student"); var p2 = new Person("Tom", 23, "Teacher"); console.log(p1); console.log(p2);
結果,每個實例都會有自己的一份實例屬性的副本,但同時又共享著對方法的引用,最大限度地節省了內存。
另外,這種混合模式,還支持向構造函數傳遞參數。
2.不同之處看上面的代碼,你會發現有個不同之處:Person.prototype的constructor屬性默認是指向Object構造函數。
從何而知?我們來測試一番。
// 組合使用構造函數模式和原型模式 function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friend = ["Jenny", "Court"]; } // 未使用原型模式前,Person構造函數的原型對象的constructor指向Person構造函數本身 console.log("Person.prototype.constructor === Person:"); console.log(Person.prototype.constructor === Person); console.log("-----分割線-----"); Person.prototype = { // constructor: Person, //一般要認為設置,將其constructor恢復為指向Person構造函數,這里為了演示,就沒設置。 Country: "China", showName: function(){ console.log("name = " + this.name); } } // 使用原型模式,我們將Person.prototype設置為等于一個以對象字面量形式創建的新對象 // 因此,這里constructor屬性也就變成了新對象的constructor屬性,指向Object構造函數。 // Person構造函數的原型對象的constructor指向Object構造函數 console.log("Person.prototype ="); console.log(Person.prototype); console.log("-----分割線-----"); console.log("Person.prototype.constructor === Object:"); console.log(Person.prototype.constructor === Object); console.log("-----分割線-----"); console.log("Person.prototype.__proto__ === Object.prototype:"); console.log(Person.prototype.__proto__ === Object.prototype); var p1 = new Person("Mike", 20, "student"); var p2 = new Person("Tom", 23, "Teacher"); console.log(p1); console.log(p2);
未使用原型模式前,Person構造函數的原型對象的constructor指向Person構造函數本身。
使用原型模式,我們將Person.prototype設置為等于一個以對象字面量形式創建的新對象。
因此,這里constructor屬性也就變成了新對象的constructor屬性,指向Object構造函數。
所以,Person構造函數的原型對象的constructor指向Object構造函數。
console.log("Person.prototype="); console.log(Person.prototype); console.log("-----分割線-----"); console.log("Person.prototype.constructor === Person:"); //true console.log(Person.prototype.constructor === Person); //true console.log("-----分割線-----"); console.log("Person.prototype.__proto__ === Object.prototype:"); //true console.log(Person.prototype.__proto__ === Object.prototype); //true console.log("-----分割線-----"); console.log("Person.__proto__="); console.log(Person.__proto__); console.log("Person.__proto__ === Function.prototype:"); console.log(Person.__proto__ === Function.prototype); //true console.log("-----分割線-----");4.觀察p1實例對象涉及到的原型鏈
console.log("p1.prototype="); console.log(p1.prototype); console.log("-----分割線-----"); console.log("p1.__proto__="); console.log(p1.__proto__); console.log("p1.__proto__ === Person.prototype:"); console.log(p1.__proto__ === Person.prototype); //true console.log("-----分割線-----"); console.log("p1.__proto__.constructor === Person:"); console.log(p1.__proto__.constructor === Person); console.log("-----分割線-----"); console.log("p1.__proto__.__proto__="); console.log(p1.__proto__.__proto__); console.log("p1.__proto__.__proto__ === Object.prototype:"); console.log(p1.__proto__.__proto__ === Object.prototype); //true console.log("-----分割線-----");5.觀察下p1.showName屬性引用的函數
console.log("p1.showName.prototype="); console.log(p1.showName.prototype); console.log("-----分割線-----"); console.log("p1.showName.prototype.constructor="); console.log(p1.showName.prototype.constructor); console.log("-----分割線-----"); console.log("p1.showName.prototype.__proto__="); console.log(p1.showName.prototype.__proto__); console.log("p1.showName.prototype.__proto__ === Object.prototype:"); console.log(p1.showName.prototype.__proto__ === Object.prototype); //true console.log("-----分割線-----"); console.log("p1.showName.__proto__="); console.log(p1.showName.__proto__); console.log("p1.showName.__proto__ === Function.prototype:"); console.log(p1.showName.__proto__ === Function.prototype); //true console.log("-----分割線-----");原型鏈圖
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79022.html
摘要:對象是由構造函數創建而成的,所以它的指向原型鏈圖對象的原型鏈圖對象屬性引用的匿名函數的原型鏈圖 Object模式 創建一個Object實例,再為其添加屬性和方法。 這是創建自定義對象最簡單的方式。 1.創建對象 // 創建person對象 var person = new Object(); person.name = Mike; person.age = 20; person.jo...
摘要:創建對象與工廠模式的區別沒有顯示地創建對象直接將方法和屬性付給了對象沒有語句構造函數應該始終以一個大寫字母開頭。創建構造函數的實例,必須使用操作符。 構造函數模式 ECMAScript中的構造函數可用來創建特定類型的對象,像Object和Array這樣的原生構造函數。也可以創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。 1.創建對象 function Person(name...
摘要:原型模式定義構造函數,在構造函數的原型對象中定義對象的屬性和方法,并通過構造函數創建對象。,屬性存在于實例對象中,屬性不存在于實例對象中分割線操作符會在通過對象能夠訪問給定屬性時返回,無論該屬性是存在于實例中還是原型中。 原型模式 定義構造函數,在構造函數的原型對象中定義對象的屬性和方法,并通過構造函數創建對象。 1.創建對象 function Person(){}; Person....
摘要:而且在超類型的原型中定義的方法,對子類型而言也是不可見的,結果所有類型都只能使用構造函數模式。在主要考慮對象而不是自定義類型和構造函數的情況下,這個模式也不錯。 寫在前面 注:這個系列是本人對js知識的一些梳理,其中不少內容來自書籍:Javascript高級程序設計第三版和JavaScript權威指南第六版,感謝它們的作者和譯者。有發現什么問題的,歡迎留言指出。 1.原型鏈 將原型鏈作...
摘要:工廠模式用函數來封裝,以特定接口創建對象的細節。缺點不能知道對象識別的問題對象的類型不知道。復雜的工廠模式定義是將其成員對象的實列化推遲到子類中,子類可以重寫父類接口方法以便創建的時候指定自己的對象類型。 工廠模式 用函數來封裝,以特定接口創建對象的細節。 1.創建對象 function createPerson(name, age, job){ var o = new Obj...
閱讀 1432·2021-11-22 15:24
閱讀 2523·2021-10-11 11:06
閱讀 2334·2021-10-09 09:45
閱讀 2532·2021-09-09 09:33
閱讀 639·2019-08-30 15:53
閱讀 1444·2019-08-30 12:48
閱讀 678·2019-08-29 13:47
閱讀 506·2019-08-26 18:27