js高級程序設計 筆記 --- 面向對象的程序設計
1,理解對象
通過對象字面量的方式,創建一個對象,為它添加屬性和方法:
var obj = { a: 1, b:2, sayA(){ console.log(this.a)}}
1,屬性類型:
數據屬性 :
數據屬性包含一個數據值的位置。在這個位置可以讀取和寫入值。有四個特性
configurable enumerable writable value : 分為的意思為:是否能通過delete刪除(能否修改特性)、是否能通過for-in循環、是否能修改屬性的值、包含這個屬性的值
通過對象字面量創建的對象,這四個特性都為true
要修改屬性的特性,必須使用Object.defineProperty()方法,這個方法接收三個參數,對象,屬性名和 特性名稱。
訪問器屬性:
訪問器屬性不包含數據值,它們包含一對getter和setter函數,在讀取訪問器屬性時,會調用getter,此函數會返回有效的值;在寫入訪問器屬性時,會調用setter並傳入新值,這個函數負責處理數據
Configurable enumerable : 同數據屬性
get: 讀取屬性時調用,
set: 寫入屬性時調用
在屬性名的前面加_ 表示 只能通過對象的方法訪問的屬性。
定義多個屬性:
Object.defineProperties () :
讀取屬性的特性:
Object.getOwnPropertyDescriptor () : 第一個參數為 指定的對象,第二個參數為要讀取描述符的屬性名;
2,創建對象
1,工廠模式
2,構造函數模式
要創建實例,必須使用new操作符。以這種方式調用構造函數會經歷以下四個步驟: 1, 創建一個新對象; 2, 將構造函數的this指向新對象; 3,執行構造函數中的代碼; 4, 返回新對象。
構造函數的問題是: 每個方法都要在每個實例上重新創建一遍,因為有this在,根本不用在執行代碼前就把函數綁定到特定的對象上。
3,原型模式
每個函數都有一個prototype屬性,這個指針指向該函數的原型對象。使用原型對象可以讓所有實例共享它所包含的屬性和方法
可以通過實例去訪問保存在原型中的值,但不能通過對象實例重寫原型中的值。 調用Object.hasOwnProperty()可以檢查一個屬性是存在實例中還是存在原型中。
for in循環的是所有能夠通過對象訪問的、可枚舉的屬性。既包含存在於實例的也包含存在於原型的屬性。
Object.keys() : 獲取對象自身所有的可枚舉的屬性值,不包括原型的屬性,返回屬性組成的數組。
Object.getOwnPropertyNames() : 獲取對象自身的所有屬性,包括不可枚舉的,不包括原型的。 返回組成的數組。
原型對象的問題是: 所有屬性都是被實例共享的,那麽如果有一個引用類型的屬性,如果一個實例修改了,那麽所有實例的這個屬性都會修改。
4,組合使用構造函數和原型對象
實例屬性在構造函數中定義,方法在原型對象中定義。
5,動態原型模式
通過構造函數來初始化原型,通過判斷 原型中沒有,再添加。
6,寄生構造函數模式
在函數中new一個對象,將參數放入這個對象,返回這個對象。 這個對象和構造函數、構造函數的原型沒有任何關系。
7,穩妥構造函數模式
適合在安全的環境,不使用this,不使用new,返回一個對象,只能通過對外的接口來訪問其中的原始數據成員。 這個對象和構造函數
3,繼承
1,原型鏈
function Person(){}
function Men () {}
Men.prototype = new Person()
Men.prototype.constructor = Men
Men的實例查找一個屬性的時候,會先在實例上查找,如果沒有的話,就在實例的原型,也就是Men.prototype上查找,如果沒有,則會繼續沿著原型鏈向上,在Person的prototype上查找,如果沒有,則繼續向上,在Object.prototype上查找。
確定原型和實例的關系
1,使用instanceof : 只要實例與原型鏈中出現過的構造函數,都會返回true
2,使用 isPrototypeOf() : 只要是原型鏈中出現過的原型,都會返回true
謹慎的定義方法
使用原型鏈繼承方法的時候,不能使用對象字面量創建原型方法,因為這樣會重寫原型鏈。
原型鏈的問題
因為在通過原型繼承的時候,原型會變成另一個類型的實例,那麽,原先的實例屬性就變成了現在的原型屬性了。 如果修改的話,會影響所有實例。
2,借用構造函數
子類的構造函數中, 使用 父類構造函數.call(this, ...args),此方法可以在子類構造函數中向超類構造函數傳遞參數。
這種方法的問題是: 超類的原型 對子類來說是不可見的。
3,組合繼承
將原型鏈和借用構造函數的技術組合。
function Person (name) { this.name = name}
Person.prototype.sayName = function (){ console.log(this.name) }
function Men (name) { Person.call(this, name) }
Men.prototype = new Person()
Men.prototype.constructor = Men
4,原型式繼承
js高級程序設計 筆記 --- 面向對象的程序設計