工廠模式javascript
構造函數模式html
原型模式java
function createPerson(name, age){ var obj = new Object(); obj.name = name; obj.age = age; return obj; //必定要返回,不然打印undefined:undefined } var person1 = new createPerson('Young',18); console.log(person1.name + ':' + person1.age);
優勢:工廠模式能夠解決建立多個類似對象函數
缺點:沒有解決對象識別問題(怎樣肯定一個對象的類型)學習
學習判斷對象類型: http://www.cnblogs.com/flyjs/...this
function Person(name,age){ this.name = name; this.age = age; } var person1 = new Person('Young',18); console.log(person1.name + ':' + person1.age);
在說優缺點以前,先來講說她自己的一點小故事吧prototype
function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ return this.name; } } //當作構造函數使用 var person1 = new Person('Young', 18); person1.sayName(); console.log(person1.name + ':' + person1.age); //當作普通函數調用 Person('Wind', 18); console.log(window.sayName()); //在另外一個做用域中調用 var obj = new Object(); Person.call(obj, 'bird', 100); console.log(obj.sayName());
優勢:能夠將它的實例標識爲一種特定類型code
缺點:每一個方法都要在每一個實例上從新建立一遍。固然你也能夠這樣改:htm
function Person(name, age){ this.name = name; this.age = age; this.sayName = sayName; } function sayName(){ return this.name; }
改成調用全局函數,這樣一來毫無封裝性可言。。。接下來的原型模式能夠彌補這個的不足對象
function Person(){ } Person.prototype.name = 'Young'; Person.prototype.age = 18; Person.prototype.sayName = function(){ return this.name; } var person1 = new Person(); console.log(person1.sayName()); var person2 = new Person(); console.log(person1.sayName()); alert(person1.sayName === person2.sayName); //person1和person2訪問的是同一組屬性的同一個sayName()函數
雖然能夠經過對象實例訪問保存在原型中的值,但卻不能經過實例對象重寫原型中的值
function Person(){ } Person.prototype.name='Young'; Person.prototype.age=18; Person.prototype.sayName=function(){ return this.name; } var person1=new Person(); var person2=new Person(); person1.name='Wind'; console.log(person1.sayName());//Wind console.log(person2.sayName());//Young alert(person1.sayName==person2.sayName);//true
在咱們調用person1.sayName的時候,會前後執行兩次搜索,解析器先肯定實例person1是否有sayName的屬性,有則調用本身的屬性,沒有則搜索原型中的屬性。
function Person(){ } Person.prototype.name='Young'; Person.prototype.age=18; Person.prototype.sayName=function(){ return this.name; } var person1=new Person(); var person2=new Person(); person1.name='Wind'; console.log(person1.sayName());//Wind console.log(person2.sayName());//Young delete person1.name; console.log(person1.sayName());//Young console.log(person2.sayName());//Young
使用hasOwnPropertyType方法能夠檢測一個屬性是存在與原型中仍是存在於實例中,該方法是從Object繼承來的,實例中爲true,原型中爲false。
function Person(){ } Person.prototype.name='Young'; Person.prototype.age=18; Person.prototype.sayName=function(){ return this.name; } var keys=Object.keys(Person.prototype); console.log(keys);//["name", "age", "sayName"]
原型模式優缺點
優勢:不用每一個方法都要在每一個實例上重申一遍
缺點:不多有人單獨使用原型模式地。。問題詳列
function Person(){ } Person.prototype={ constructor:Person, name:'Young', age:18, friends:['Big','Pig'], sayName:function(){ return this.name; } }; var p1=new Person(); var p2=new Person(); p1.friends.push('Mon'); console.log(p1.friends);//["Big", "Pig", "Mon"] console.log(p2.friends);//["Big", "Pig", "Mon"]
正是由於實例通常都要有本身的屬性,而咱們這裏將他放在了Person.prototype中,因此隨着p1的修改,整個實例包括原型都修改了。那麼,咱們能夠組合使用構造函數模式和原型模式。
function Person(name,age){ this.name=name; this.age=age; this.friends=['Big','Pig']; } Person.prototype={ sayName:function(){ return this.name; } }; var p1=new Person('Young',18); var p2=new Person('Wind',78); p1.friends.push('Raganya'); console.log(p1.friends);//["Big", "Pig", "Raganya"] console.log(p2.friends);//["Big", "Pig"] console.log(p1.friends==p2.friends);//false console.log(p1.sayName==p2.sayName);//true
這種模式是目前使用最普遍、認同度最高的一種建立自定義類型的方法。是用來定義引用類型的一種默認模式。