• 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两种模式较为常用。

  • 相关阅读:
    数组中只出现一次的数字
    平衡二叉树
    二叉树的深度
    数字在排序数组中出现的次数
    数组中的逆序对
    第一个只出现一次的字符位置
    丑数
    把数组排成最小的数/1038. Recover the Smallest Number
    python系统编程(十一)
    python系统编程(十)
  • 原文地址:https://www.cnblogs.com/mengjingmei/p/9383372.html
Copyright © 2020-2023  润新知