標籤:ges 方法 .com 建構函式 支援 type pre 提取 取出
建立一個對象,先來看一段代碼:
// 例如建立一個 Person 的建構函式, 讓人有名字, 可以說話function Person ( name ) { this.name = name; // 可以說話, 需要有一個方法 this.sayHello = function () { console.log( ‘你好, 我是 ‘ + this.name ); };}var p1 = new Person( ‘小明‘ );var p2 = new Person( ‘大偉‘ );console.log( p1.sayHello == p2.sayHello ); // false
說明p1的sayHello()方法 和 p2的sayHello()方法 不相同。也就間接的說明每次建立一個執行個體化對象的時候都會在記憶體中重新開闢一個儲存空間進行建立,一旦頻繁建立執行個體化的對象時,會造成記憶體資源的浪費 。
解決方案 將公用的方法提取出來進行函數封裝 (缺點: 代碼比較亂、命名衝突幾率大) 將所有方法都綁定到對象的屬性上(雖然 提高了代碼可讀性、也減少了命名衝突,貌似還是可以進行最佳化) JS 原生就支援解決方案: 每個函數都有一個 prototype(原型)屬性,
將共用的方法綁定到 .prototype 原型上 即可
// 例如建立一個 Person 的建構函式, 讓人有名字, 可以說話function Person ( name ) { this.name = name; // 可以說話, 需要有一個方法 this.prototype.sayHello = function () { console.log( ‘你好, 我是 ‘ + this.name ); };}var p1 = new Person( ‘小明‘ );var p2 = new Person( ‘大偉‘ );console.log( p1.sayHello == p2.sayHello ); // true
說明p1與p2訪問的是同一組屬性,同一個sayHello()方法。間接的說明用原型綁定公用的方法(共用一個儲存空間)
原型的使用
constructor(構造器):每個建構函式被建立出來都有一個prototype(原型)屬性,每個原型屬性都有個constructor屬性,該屬性預設指向 原建構函式。
// 首先需要建構函式, 原則就是將專屬的方法放在 對象中 function Person ( name, age, gender ) { this.name = name; this.age = age; this.gender = gender; } 將共用的方法放到預設的 .prototype 原型中,而專屬的資料與行為放到對象中
// 將共用的方法提取出來 Person.prototype.sayHello = function () { console.log( ‘你好, 我是 ‘ + this.name ); }; Person.prototype.eat = function () { console.log( this.name + ‘在吃飯‘ ); }; Person.prototype.run = function () { console.log( this.name + ‘在跑步. 已經跑了 ‘ + this.age + ‘ 年‘ ); }; // 直接給原型對象新增成員 var p1 = new Person( ‘lilei‘, 19, ‘男‘ ); var p2 = new Person( ‘hanmeimei‘, 18, ‘女‘ ); 給原型 .prototype屬性 重新賦值 ,將原來預設的 .prototype 覆蓋掉
// 讓 Person.prototype 指向另一個對象. 直接賦值 Person.prototype = { constructor: Person, //constructor 預設指向 Object ,將其改為指向 原建構函式 sayHello: function () { console.log( ‘第二種做法: 你好, 我是 ‘ + this.name ); }, eat: function () { console.log( ‘第二種做法: ‘ + this.name + ‘ 在吃飯‘ ); }, run: function () { console.log( ‘第二種做法: ‘ + this.name + ‘ 在跑步. 已經跑了 ‘ + this.age + ‘ 年‘ ); } }; var p1 = new Person( ‘lilei‘, 19, ‘男‘ ); var p2 = new Person( ‘hanmeimei‘, 18, ‘女‘ ); 如果訪問的對象的某個方法時,執行個體化的對象上沒有該方法,就會到該對象的原型 . prototype 上去找 下面是一個簡單的 原型結構 分析圖: 建構函式 ---------- 使用 prototype 屬性 ----- 訪問原型 執行個體對象 ---------- 使用 __proto__屬性 ----- 訪問原型 針對建構函式而言,原型就是 建構函式的 prototype 屬性 ---
原型屬性 針對執行個體對象而言,原型就是 執行個體對象的 __ptoto__屬性 ---
原型對象
JS中的原型模式