javascript對象的幾種建立方式javascript
總共有如下幾個模式:java
1.工廠模式 2.構造函數模式 3.原型模式 4.混合構造函數和原型模式 5.動態原型模式 6.寄生構造函數模式 7.穩妥構造函數模式
1.工廠模式:windows
<script type="text/javascript"> function Person(name,sex) { var obj=new Object(); obj.name=name; obj.sex=sex; obj.getSex=function(){ alert(this.sex); } return obj; } var person=new Person("張三","男") alert(person.name); person.getSex(); </script>
缺點:不能識別出對象的類型。數組
2.構造函數模式安全
<script type="text/javascript"> function Person(name,sex) { this.name=name; this.sex=sex; this.getSex=function(){ alert(this.sex); } } var person=new Person('張三','男'); alert(person.name); person.getSex(); </script>
使用構造函數模式能夠有三種創造方式:app
(1)看成構造函數去使用函數
var person=new Person();this
(2) 看成普通函數去使用spa
var person=Person();可是這種方式默認this是windows,至關於直接在全局範圍內定義name,sex屬性。prototype
(3)使用call
var person=new Object();
Person.call(person,"張三","男");
alert(person.name); //張三
缺點:因爲this指針在對象實例的時候發生改變指向新的實例。這時新實例的方法也要從新建立,若是n個實例就要n次重建相同的方法
3.原型模式
<script type="text/javascript"> function Person() { } Person.prototype={ constructor:Person, //必須設置這個屬性,否則就斷了與構造函數的聯繫了。沒有實例共享原型的意義了。 /* 如今這個屬性是可枚舉的,若不想被枚舉,則能夠使用以下代碼 參數:重設構造器的對象,所要設置的屬性,可選設置 Object.definePropery(Person.prototype,'constructor',{ enumerable:false, value:Person }) */ name:'張三', sex:'男', getSex:function(){ alert(this.sex); } } var person=new Person(); alert(person.name); person.getSex(); </script>
調用方法的過程:先看實例中有沒有,有調之,無追蹤到原型,有調之,無出錯,調用失敗。
缺點:這種純原型的模式問題也很明顯,全部的屬性,方法和變量都是共享的,一旦修改一個所有都會受影響,不能讓對象具體化。
4.混合構造和原型模式
<script type="text/javascript"> function Person(name,sex) { this.name=name; this.sex=sex; } Person.prototype={ constructor:Person, //必須設置這個屬性,否則就斷了與構造函數的聯繫了。沒有實例共享原型的意義了。 /* 如今這個屬性是可枚舉的,若不想被枚舉,則能夠使用以下代碼 參數:重設構造器的對象,所要設置的屬性,可選設置 Object.definePropery(Person.prototype,'constructor',{ enumerable:false, value:Person }) */ getSex:function(){ alert(this.sex); } } var person=new Person("張三","男"); alert(person.name); person.getSex(); </script>
推薦:應用最普遍。
5.動態原型模式
<script type="text/javascript"> function Person(name,sex) { this.name=name; this.sex=sex; //動態原型方法 只會執行一次 if(typeof this.getSex!='function') { Person.prototype.getSex=function(){ alert(this.sex); } } } var person=new Person("張三","男"); alert(person.name); person.getSex(); </script>
推薦
5.寄生構造函數模式
這種模式的基本思想是建立一個函數
,該函數的做用僅僅是封閉建立對象的代碼
,而後再返回新建立的對象.
假設咱們想建立一個具備額外方法的特殊數組。因爲不能直接修改Array構造函數,能夠使用這個模式。
function SpecialArray() { //建立數組 var values = new Array(); // 添加值 values.push.apply(values, arguments); // 添加方法 values.toPipedString = function() { return this.join('|'); }; // 返回數組 return values; } var colors = new SpecialArray('red', 'blue', 'green'); alert(colors.toPipedString());//red|blue|green;
在這個例子中,咱們建立了一個名叫SpecialArray的構造函數。在這個函數內部,首先建立了一個數組,而後push()方法(用構造函數接收到的全部參數)初始化了數組的值。隨後,又給數組實例添加了一個toPipedString()方法,該方法返回以豎線分割的數組值。最後,將數組以函數值的形式返回。接着,咱們調用了SpecialArray構造函數,向其中傳入了用於初始化數組的值,此後調用了toPipedString()方法。
關於寄生構造函數模式,有一點須要說明:首先,返回的對象與構造函數或構造函數的原型屬性之間沒有關係;也就是說,構造函數返回的對象與在構造函數外部建立 對象沒有什麼不一樣。爲此,不能依賴instranceof操做符來肯定對象類型。因爲存在上述問題,建議在能夠使用其餘模式的狀況下,不要使用這種模式。
6.穩妥構造函數模式
<script type="text/javascript"> function Person(name,sex) { var object=new Object(); var name=name; var sex=sex; object.getSex=function(){ alert(sex); } return object; } var person=new Person("張三","男"); alert(person.name); //undefined person.getSex(); //男 </script>
沒有公共屬性,其餘方法也不引用this對象,只能經過存取器得到變量的值,適合對安全性要求很高的程序。
還有不能被稱爲模式的方法,只能實例單個對象:
1.簡單對象字面量
//建立一個簡單對象字面量 var person = {}; // 加入屬性和方法 person.name = 'ifcode'; person.setName = function(theName) { person.name = theName; }
很是簡單,但通常狀況下不推薦這種方法。JS good parts書中認爲這種寫法可讀性不夠強,做者推薦的是後面一種寫法。
2.嵌套對象字面量
var person = { name: 'ifcode', setName: function(theName) { this.name = theName; } }
JS good parts中推薦這種寫法: