對象(二)
創建對象的方式:
1、使用原生引用類型Object()
//使用引用Object創建 new Object() var obj1=new Object(); obj1.name="obj1"; obj1.num=1;
2、對象字面量創建
var obj2={ name:"obj2", num:2 };
這兩種方式的缺點: 當需要創建很多對象的時候,會產生大量的重復代碼
3、工廠模式 用函數來封裝以特定接口創建對象
function obj3(name,num){ var b=new Object(); //顯示的引用Object創建對象b.name=name; b.num=num; b.sayName=function(){ alert(this.name); }; return b; //return 回一個對象 } var people=obj3("obj3",3); //並未使用new 而是直接調用函數,返回一個對象
可以無數次的調用obj3函數,每次都return 一個包含兩個屬性和一個方法的對象;
缺點:無法解決對象識別問題;
4、構造函數模式(創建自定義構造函數)
//構造函數模式 function Person(name,num){ this.name=name; this.num=num; this.sayname=function(){ alert(this.name); } } var person1=new Person("obj4",4);
與工廠模式的不同:1、沒有顯示的創建對象;
2、直接將屬性和方法賦值給this;
3、沒有return 語句;
實例person1保存著一個屬性constructor==Person(等於構造函數),對象的constructor屬性最初就是用來標識對象的;這正是構造函數模式勝過工廠模式的地方;
缺點:每個方法都要在每個實例對象上重新創建一遍;
5、原型模式:構造函數有一個prototype屬性,指向原型對象,而這個原型對象包含由構造函數創建的實例共享的所有屬性和方法;
所有原型對象都有一個constructor屬性,指向構造函數
//原型模式 function Person5(){}; //自定義構造函數 為空 Person5.prototype={
constructor:Person, name:"china", num:5, sayname:function(){ alert(this.name); } }; var obj5=new Person5();
缺點:省略了為構造函數傳參,結果所有實例在默認情況下都將獲得相同的屬性值,對於引用類型值得屬性,只要有一個實例push到一個數組中值,那麽其他實例也會獲得這個新值,這就是為什麽不單獨使用原型模式的原因;
6、構造函數和原型模式組合使用 構造函數模式用於定義實例屬性;原型模式用於定義方法和共享屬性;
//構造函數和原型模式組合使用 function Person6(name,num){ // prototype:Person.prototype; this.name=name; this.num=num; } Person6.prototype={ constructor:Person6, sayname:function(){ alert(this.name); } } var obj6=new Person6("obj6",6);
補充:
1、檢測對象類型:instanceof
實例 instancsof 構造函數 //true
2、檢測實例的原型是否有某一對象
只有實例的prototype屬性指向的對象才返回true; 原型.isPrototypeOf(實例)
Person6.prototype.isPrototypeOf(obj6) //true
Object.isPrototypeOf(obj6) //false
3、Object.getPrototypeOf() 識別原型
alert(Object.getPrototypeOf(obj6)==Person6.prototype); //true alert(Object.getPrototypeOf(obj6)==Object); //false
4、hasOwnProperty() 檢測一個屬性是否存在於實例中還是原型中 只有存在於對象實例才會返回true
name必須用引號包起來,,否則為false;
obj6.name=7; console.log(obj6.hasOwnProperty("name")); //true
5、得到所有屬性無論它是否 Object.getOwnPropertyNames()
console.log(Object.getOwnPropertyNames(obj6)); console.log(Object.getOwnPropertyNames(Person6.prototype));
對象(二)