工廠模式
通過封裝一個函數來創建對象,所有的對象都是相同的,缺點是無法賦予一個對象特定的類型
function createObject(name,age,job) {
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
return o;
}
var person=createObject("John","19","teacher");
構造函數模式
這種方法沒有顯示地創建對象,而是通過this綁定對象。
按照慣例構造函數名以大寫字母開頭
function Person(name,age,job) {
this.name=name;
this.age=age;
this.job=job;
this.say=function(){
alert("hello");
}//每定義一個Person對象都會實例化一個匿名函數對象
}
var person1=new Person();//通過new來創建對象
alert(person1.constructor==Person);//true
alert(person1 instanceof Object);//true
alert(person1 instanceof Person);//true
這樣定義的對象會有一個constructor屬性
原型模式
創建的函數都有一個prototype屬性,這個屬性是一個指針,指向原型對象
function Person() {
Person.prototype.name="John";
Person.prototype.age="18";
Person.prototype.sayName=function () {
alert(this.name);
}
}
var person1=new Person();
alert(person.name);//"John"
alert(Person.prototype.constructor==Person);//true
alert(Person.prototype.isPrototypeOf(person1));//true
person1這個對象會有一個屬性{[prototype]}指向Person.prototype,
但person1這個對象和Person函數之間沒有直接聯繫
接下來談談關於原型的一些方法
- hasOwnProperty() 實例屬性返回true,原型屬性返回false;
- in 對象能訪問該屬性時返回true,無論實例屬性還是原型屬性都一樣
alert("name" in person1);//true
- for in 循環返回能夠通過對象訪問的可枚舉的屬性(包括原型中和實例中的),如果實例屬性覆蓋了原型中不可枚舉的屬性,該實例屬性也會返回,但是在IE8以及更早的版本中,該實例屬性不會返回。
不可枚舉的屬性和方法有:
- hasOwnProperty();
- propertyIsEnumberable( );
- toLocaleString( );
- toString( );
- valueOf( );
- keys( ) 返回對象所有可枚舉的實例屬性,對象作爲參數,返回值是一個可枚舉屬性的字符串數組,順序與for in相同
- Object.getOwnPropertyNames( ) 返回所有實例屬性,無論能否枚舉 (IE9+,Firefox4+,Safari5+,Opera12+,Chrome支持以上兩個方法)
原型的其他寫法
function Person() {
}
Person.prototype={
name:"John",
age:20,
job:"Doctor"
};
這樣寫constructor不在指向Person
可以在Person.prototype中顯式的聲明constructor,但這樣這個屬性會變成可枚舉的,可以用Object.defineProperty( )替代,這個方法適用於兼容ES5及以上的瀏覽器
Object.defineProperty(Person.prototype,"constructor"
,{
enumberable:false,
value:Person
});
原型的動態性
原型的動態性在於可以在通過原型方法定義對象後,修改原型,此時對象也會相應變化
但是如果重新定義原型,對象與新原型之間則沒有聯繫,原因在於,對象與構造函數之間是沒有之間聯繫的
最後的問題是可以修改對象的原型屬性達到修改原型的目的