106_js筆記9_js類和建構函式
阿新 • • 發佈:2018-11-30
一,類的定義
- 通過建構函式來定義
- 大駝峰命名法
- 通過new來呼叫
- 對比工廠法,不用手動建立物件和返回值
function Person(name, age) { this.name = name; this.age = age; this.say = function () { console.log(this.name, this.age); } }
二,建構函式
- 程式碼簡潔,識別物件的具體型別
- 每個物件都可以訪問一個名稱叫做constructor的屬性, 屬性指向建立該例項的建構函式,
- 通過constructor判斷一個物件是否屬於某個類(p instanceof Person或者p.constructor === Person)
- 防止記憶體浪費和函式方法重名,可以把需要共享的函式定義到建構函式外部
-
// 將共享函式封裝到一個物件中, 與外界隔絕, 這樣就不會汙染全域性名稱空間了 var fns = { say: function () { console.log(this.name, this.age, this.type); }, setName: function (name) { this.name = name; }, setAge: function (age) { this.age = age; } } function Person(name, age) { this.name = name; this.age = age; this.type = "人"; this.say = fns.say; this.setName = fns.setName; this.setAge = fns.setAge; } var p1 = new Person("jj", 33); var p2 = new Person("zs", 33); console.log(p1.say === p2.say); // true
-
- 建構函式的優化方法
- 建構函式、例項、原型三者之間的關係()
- 當呼叫物件的屬性或者方法的時候,先去找物件本身的屬性/方法
- 如果物件沒有該屬性或者方法。此時去原型中查詢對應的屬性/方法
- 如果物件本身沒有該屬性/方法,原型中也沒有該屬性或者方法,此時會報錯
-
function Person(name, age) { this.name = name; this.age = age; } // 給原型物件新增新的屬性和方法 Person.prototype.say = function () { console.log(this.name, this.age, this.type); }; Person.prototype.type = "人"; var p1 = new Person("jj", 33); var p2 = new Person("zs", 33); console.log(p1.say === p2.say); // true console.log(p1.type === p2.type); // true // 當呼叫物件的屬性或者方法的時候,先去找物件本身的屬性/方法 // 如果物件沒有該屬性或者方法。此時去原型中查詢對應的屬性/方法 // 如果物件本身沒有該屬性/方法,原型中也沒有該屬性或者方法,此時會報錯 p1.say(); console.log(p1.type);
- 原型鏈上方法呼叫
- 先查詢當前物件, 當前物件有就使用當前物件的方法
- 當前物件沒有再逐層在原型鏈上查詢, 最先找到那個就使用哪個
- 如果找到null都沒找到就報錯
-
function Person(name, age) { this.name = name; this.age = age; this.say = function () { console.log("自己的", this.name, this.age); }; } // 給原型物件新增新方法 Person.prototype.say = function () { console.log("原型鏈上的", this.name, this.age); }; var p = new Person("jj", 33); // 自己有嗎? 有, 使用自己的 // 自己有嗎? 沒有, 去原型鏈查詢 // 都沒有嗎? 報錯 p.say(); 結果: 自己的 jj 33
- 原型鏈上屬性設定
- 先查詢當前物件, 當前物件有就使用當前物件的方法
- 當前物件沒有再逐層在原型鏈上查詢, 最先找到那個就使用哪個
- 如果找到null都沒找到就輸出undefined
-
function Person(name, age) { this.name = name; this.age = age; this.type = "超人"; } // 給原型物件新增新的屬性和方法 Person.prototype.type = "人"; var p = new Person("kk", 33); // 自己有嗎? 有, 使用自己的 // 自己有嗎? 沒有, 去原型鏈查詢 // 都沒有嗎? undefined console.log(p.type); 結果: 超人
-
- 原型鏈上的屬性:_ _proto_ _(下劃線沒有空格)
- 原型鏈上的屬性不會改變,改變的只是物件的屬性
-
function Person(name, age) { this.name = name; this.age = age; } // 給原型物件新增新的屬性和方法 Person.prototype.type = "人"; var p = new Person("kk", 33); console.log(p.__proto__.type); // p.__proto__.type = "超人"; // 自己有這個屬性嗎? 沒有, 新增 p.type = "超人"; console.log(p.__proto__.type); console.log(p.type); 結果: 人 人 超人
- 自定義原型物件
- 原型物件是建構函式的一個屬性, 所以我們可以通過修改屬性值的方式來自定義原型物件
-
function Person(name, age) { this.name = name; this.age = age; // this.say = function () { // console.log('haha'); // } } Person.prototype = { constructor: Person, // 手動還原constructor屬性, 保持三角戀關係 type: "人", say: function () { console.log(this.name, this.age, this.type); } } var p = new Person("lnj", 33); p.say(); 結果: lnj 33 人
- 原型物件使用建議
- 私有成員(一般就是非函式成員)放到建構函式中
- 共享成員(一般就是函式)放到原型物件中
- 如果重置了 prototype 記得修正 constructor 的指向
-
-
-