7中创建对象的方式(工厂模式构造函数模式原型模式动态原型模式等分析)

Posted mengjingmei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7中创建对象的方式(工厂模式构造函数模式原型模式动态原型模式等分析)相关的知识,希望对你有一定的参考价值。

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中创建对象的方式(工厂模式构造函数模式原型模式动态原型模式等分析)的主要内容,如果未能解决你的问题,请参考以下文章

深入理解JavaScript中创建对象模式的演变(原型)

深入理解JavaScript中创建对象模式的演变(原型)

深入理解JavaScript中创建对象模式的演变(原型)

深入理解JavaScript中创建对象模式的演变(原型)

js面向对象小结(工厂模式,构造函数,原型方法,继承)

js - 创建对象的几种方式(工厂模式构造函数模式原型模式)