1. 程式人生 > >7中創建對象的方式(工廠模式、構造函數模式、原型模式、動態原型模式等分析)

7中創建對象的方式(工廠模式、構造函數模式、原型模式、動態原型模式等分析)

.proto 賦值 obb this指向 好的 eat 臨時對象 struct 類型

1、工廠模式

    // 定義工廠函數
    function createPerson(name, age, hobby) {
        // 創建一個臨時object對象
        var obj = new Object();
        // 將工廠函數的參數賦值給臨時對象
        obj.name = name;
        obj.age = age;
        obj.hobby = hobby;
        obj.sayName = function() {
            console.log("我的名字叫:"+this.name);
        }
        // 返回這個包裝好的臨時對象
        return obj;
    }
    //使用工廠函數創建對象
    var p1 = createPerson(‘Tom‘, 12, "sing");
    var p2 = createPerson(‘mayra‘, 18, "draw");
        

解決問題:用於創建的批量相似對象

2、構造函數模式

    // 定義構造函數
    function Person(name, age, hobby) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.sayName = function() {
            console.log("我的名字叫:"+this.name);
        }
    }
    // 使用構造函數實例化
    var p1 = new Person(‘Tom‘, 12, "sing");
    var p2 = new Person(‘mayra‘, 18, "draw");

步驟分析:

  1. 使用new關鍵字在內存中創建一個新對象;
  2. 將構造函數的this指向這個新對象;
  3. 使用this為這個對象添加屬性和方法
  4. 返回這個對象

解決的問題:構造函數可以將實例化的對象標識為一種特定的類型

存在的問題:相同的方法每次實例化都要重新創建一遍,浪費內存

3、原型模式

    // 定義構造函數
    function Person() {
        
    }
    // 定義原型
    Person.prototype = {
        constructor: Person,  //重寫constructor
        name: ‘Tom‘,
        books: [‘數學‘,‘英語‘], // 引用類型
        country: "china", // 共享屬性
        sayName: function () {  // 共享方法
            console.log("我的名字叫:" + this.name);
        },
    };
    // 使用構造函數實例化
    var p1 = new Person();
    var p2 = new Person();
    p1.books.push(‘語文‘);
    console.log(p1.books);  // ‘數學‘,‘英語‘,‘語文‘
    console.log(p2.books);  // ‘數學‘,‘英語‘,‘語文‘    p1實例影響到p2!!!

問題:屬性和方法都定義在了原型上,1、不能傳參構造不同屬性的對象 2、對於包含引用類型值的屬性來說,實例之間會相互影響

這種單獨使用原型模式的方法基本沒人使用!

4、構造函數模式和原型模式組合使用(默認使用的模式!!!)

    // 定義構造函數
    function Person(name, age, hobby) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        this.books = [‘數學‘,‘英語‘]; //引用類型
    }
    // 定義原型(定義共享的屬性)
    Person.prototype = {
        constructor: Person,  //重寫constructor
        country: "china", // 共享屬性
        sayName: function () {  // 共享方法
            console.log("我的名字叫:" + this.name);
        },
    };
    // 使用構造函數實例化
    var p1 = new Person(‘Tom‘, 12, "sing");
    var p2 = new Person(‘mayra‘, 18, "draw");
    p1.books.push(‘語文‘);
    console.log(p1.books);  // ‘數學‘,‘英語‘,‘語文‘
    console.log(p2.books);  // ‘數學‘,‘英語‘    p1實例不會影響到p2!!!
    console.log(p1.country);  // china
    console.log(p2.country);  // china
    p1.sayName();   // 我的名字叫:Tom
    p2.sayName();   // 我的名字叫:mayra

解決了構造函數模式共享方法多次創建問題,也解決了原型模式出現引用類型屬性時存在的問題,目前最為常用的方式

5、動態原型模式

特點:將所有信息都封裝在構造函數類,動態初始化原型

    // 定義構造函數
    function Person(name, age, hobby) {
        this.name = name;
        this.age = age;
        this.hobby = hobby;
        //  判斷當前是否具有sayName方法,沒有就初始化原型添加該方法
        if(typeof this.sayName != ‘function‘) {
            // 這個只會在第一次使用構造函數時執行
            Person.prototype.sayName = function () {
                console.log("我的名字叫:" + this.name);
            }
        }

    }
    // 使用構造函數實例化
    var p1 = new Person(‘Tom‘,13,‘sing‘);
    var p2 = new Person(‘bob‘,16,‘draw‘);
    p1.sayName();
    p2.sayName();  
    

解決問題:這樣構造函數更像一個整體

6、寄生構造函數模式

    function Person(name, age, hobby) {
        // 創建一個臨時object對象
        var obj = new Object();
        // 將參數賦值給臨時對象
        obj.name = name;
        obj.age = age;
        obj.hobby = hobby;
        obj.sayName = function() {
            console.log("我的名字叫:"+this.name);
        };
        // 返回這個包裝好的臨時對象
        return obj;
    }
    //使用函數創建對象
    var p1 = new Person(‘Tom‘, 12, "sing");
    var p2 = new Person(‘mayra‘, 18, "draw");

其實就是構造函數樣子的工廠模式,意義不大,不推薦使用

7、穩妥構造函數模式

    function Person(name) {
        // 創建一個臨時object對象
        var obj = new Object();
        
        obj.sayName = function() {
            console.log(this.name);
        };
        // 返回這個包裝好的臨時對象
        return obj;
    }
    //函數創建對象
    var p1 = new Person(‘Tom‘);
    var p2 = new Person(‘mayra‘);
    p1.sayName(); //Tom  只能通過這一種方式訪問name的值

用處:提供固定訪問成員的方法,適合在某些安全執行環境

以上不同環境下適合使用不同的模式創建對象,4、5兩種模式較為常用。

7中創建對象的方式(工廠模式、構造函數模式、原型模式、動態原型模式等分析)