沒有解決對象識別的問題(即怎樣知道一個對象的類型)函數
function createPerson(name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function() { alert(this.name); }; return o; } var person1 = createPerson("Nicholas",29,"Software Engineer");
使用構造函數的主要問題,就是每一個方法都要在每一個實例上從新建立一遍。經過把函數定義轉移到構造函數外部來解決這個問題this
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { alert(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); //把函數定義轉移到構造函數外部 function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var person1 = new Person("Nicholas", 29, "Software Engineer");
若是對象須要定義不少方法,那麼就要定義不少個全局函數,因而咱們這個自定義的引用類型就絲毫沒有封裝性可言了。prototype
原型對象的好處是可讓全部對象實例共享它所包含的屬性和方法;
原型模式最大的問題是由其共享的本性致使的:對於那些包含基本值的屬性能夠經過在實例上添加一個同名屬性,能夠隱藏原型中的對應屬性,可是對於包含引用類型值的屬性來講,問題就很突出了。code
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName();
建立自定義類型的最多見方式就是組合使用構造函數模式與原型模式;
構造函數模式用於定義實例屬性,而原型模式用於定義方法和共享的屬性。對象
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } Person.prototype = { constructor : Person, sayName : function() { alert(this.name); } } var person1 = new Person("Nicholas",29,"Software Engineer");
經過檢查某個應該存在的方法是否有效來決定是否須要初始化原型;
注意:使用動態原型模式時,不能使用對象字面量重寫原型。若是在已經建立了實例的狀況下重寫原型,那麼就會切斷現有實例與新原型之間的聯繫;原型
function Person(name, age, job) { this.name = name; this.aghe = age; this.job = job; if(typeof this.sayName !="function") { Person.prototype.sayName = function(){ alert(this.name); }; } } var friend = new Person("Nicholas",29,"Software Engineer");
封裝建立對象的代碼,而後再返回新建立的對象;
除了使用new操做符並把使用的包裝函數叫作構造函數以外,這個模式和工廠模式實際上是如出一轍的io
function Person (name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function() { alert(this.name); }; return o; } var friend = new Person("Nicholas", 29, "Software Engineer");
穩妥構造函數遵循與寄生構造函數相似的模式,但有兩點不一樣:
(1)新建立對象的實例方法不引用this;
(2)不使用new操做符調用構造函數。function
function Person(name, age, job) { var o = new Object(); //建立要返回的對象 //能夠在這裏定義私有變量和函數 o.name = name; o.age = age; o.job= job; //添加函數 o.sayName = function() { alert(name); //注意寄生構造函數中是alert(this.name) }; //返回對象 return o; } //注意寄生構造函數中是var friend = newPerson("Nicholas", 29, "Software Engineer"); var friend = Person("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas"