面向面試編程——javascript對象的幾種建立方式

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中推薦這種寫法:
相關文章
相關標籤/搜索