標籤:function 包含 屏蔽 var 參考 構造 spro 改變 自訂
Javascript建立對象幾種方法解析
Javascript物件導向編程一直是面試中的重點,將自己的理解整理如下,主要參考《Javascript進階程式設計 第三版》,歡迎批評指正。
通過字面量形式,建立對象:
var person_1 = { name: "userName", age: 20 }
原廠模式建立對象
通過一個建構函式接收參數的方式構造對象,可無數次調用這個函數,通過改變參數構造不同的對象
function createPerson(name,age){ var o = new Object();//建立一個空的對象 -- 原料 o.name = name; o.age = age; o.sayName = function(){ //給對象屬性賦值 -- 加工過程 alert(this.name) } return o; //返回加工後的對象 -- 出廠 } //var leo = createPerson(‘Leo‘,30); //leo.sayName(); //"Leo" //var cherry = createPerson(‘Cherry‘,20); //cherry.sayName(); //"Cherry"
缺點:原廠模式建立的對象,無法判斷其類型
建構函式模式:
類似Array,Object這種原生的建構函式,我們可以通過建立自訂的建構函式,從而定義自訂對象的類型和方法
function Person(name,age){ this.name = name; this.age = age; this.sayName = function(){ alert(this.name); } } var leo = new Person(‘Leo‘,18); var cherry = new Person(‘Cherry‘,25); leo.sayName(); cherry.sayName();
- 與原廠模式對比,幾點不同:沒有現實的建立Null 物件;直接將屬性和方法賦值給this;不需要return
- 通過New操作符建立Person對象的新執行個體:①建立一個新的對象 ②this指向這個新對象(範圍)③執行建構函式中的代碼,對新對象添加屬性和方法④返回新對象
通過instanceof檢測物件類型,發現通過Person建構函式建立的對象,即使Person類的執行個體,又是Object對象的執行個體 - 建立自訂的建構函式表明可以將它的執行個體標識為一種特定的類型
alert(leo instanceof Person); //true alert(leo instanceof Object); //true 所有對象都繼承自Object
區分建構函式和普通函數
①. 任何函數通過new操作符調用,就可做為建構函式
②. 自訂的建構函式,不通過new調用,與普通函數沒有區別
Person(‘window‘,100);//直接調用,相當於將Person類的屬性方法直接添加到了this上 window.sayName(); //window
缺點:通過建構函式,每個方法都要在執行個體上重新建立一遍,每個執行個體的sayName方法,相當於執行this.sayName = new Function("alert(this.name)")
單獨建立出來的
alert(leo.sayName==cherry.sayName);//false
原型模式:
建立的每個函數都有prototype屬性,這個屬性指向一個其屬性和方法由某個特定類的所有執行個體共用的對象,利用prototype,我們就可將定義對象執行個體的資訊放在原型對象中,不必在建構函式中定義。
function Person(){} //建構函式變成空 Person.prototype.name = ‘Leo‘; Person.prototype.age =30; Person.prototype.sayName = function(){ alert(this.name); } var person1 = new Person(); var person2 = new Person(); alert(person1.sayName==person2.sayName);//true 將sayName方法定義在Person的prototype屬性中,可由多個不同的執行個體共用 //簡化寫法: function Person() { } //建構函式變成空 Person.prototype = { name: ‘Leo‘, age: 30, sayName: function () { alert(this.name); } } var person1 = new Person(); var person2 = new Person();
只要建立一個新函數,就會為該函數建立一個prototype屬性,這個屬性指向原型對象。在我們建立的對象person1和person2中都包含一個內部屬性,該屬性指向Person.prototype,因此兩個執行個體都可以調用原型中的sayName()方法。Object.getPrototypeOf()方法可以更方便的取得一個對象的原型.
alert(Person.prototype.isPrototypeOf(person1));//true alert(Person.prototype.isPrototypeOf(person2));//true alert(Object.getPrototypeOf(person1)==Object.getPrototypeOf(person2));//true
給一個對象添加一個屬性,這個屬性會屏蔽原型對象中儲存的同名屬性,通過hasOwnProperty()方法可判斷是執行個體對象中的屬性,還是原型中的屬性;通過in運算子,可以判斷在對象上能否找到某屬性,而不區分是執行個體屬性還是原型屬性,for in迴圈中只會遍曆可訪問、可枚舉的屬性。
person1.name=‘Nancy‘; alert(person1.name);//Nancy alert(person1.hasOwnProperty("name"));//True 執行個體對象上的屬性 alert(person2.hasOwnProperty("name"));//false 原型中的屬性 alert("name" in person1);//true alert("name" in person2);//true for(key in person1){ alert(`${key}:${person1[key]}`) }
Javascript建立對象幾種方法解析