美文网首页
JS之创建对象的方式及其优劣

JS之创建对象的方式及其优劣

作者: 晴天的晴q | 来源:发表于2018-12-21 21:39 被阅读0次

    一、工厂模式

        用函数来封装以特定接口创建对象的细节。

    function createPerson(name,age) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.sayName = function() {
            alert(this.name);
        }
        return o;
    }
    var person1 = createPerson("Dobby1", 5);
    var person2 = createPerson("Dobby2", 6);

    优点:解决了创建多个相似对象的问题;

    缺点:没有解决对象识别的问题(怎样知道一个对象的类型)。

    二、构造函数模式

    1. 不用显示的创建对象
    2. 直接将方法和属性赋给了this对象
    3. 没有return语句
    4. 函数名的首字母大写
    5. 必须使用 new 操作符创建新实例
    6. 实例对象都有一个 constructor(构造函数)属性,该属性指向构造函数
    7. 可以用 instanceof 操作符验证其类型。

    function Person(name,age) {    
        this.name = name;
        this.age = age;
        this.sayName = function() {  
           alert(this.name);
        }
        return o;
    }
    var person1 = createPerson("Dobby1", 5);
    var person2 = createPerson("Dobby2", 6);

    优点:创建自定义的构造函数意味着可以将它的实例标识为一种特定的类型;

    缺点:每个方法都要在每个实例上面重新创造一遍(ECMAScript中的函数是对象,因此每定义一个函数,也就是实例化了一个对象),也就是说,以这种方式创建对象,会导致不同的作用域链和标识符解析,但创建 Function 新实例的机制仍然是相同的。因此,不同实例上的同名函数第不相等的。

    解决上述缺点可以通过把函数定义转移到构造函数来解决这个问题。但如果对象需要定义很多方法,那么就要定义很多个全局函数,于是我们这个自定义的引用类型就丝毫没有封装性可言了。

    三、原型模式

    我们创建的每个函数,都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,该对象包含可以由特定类型的所有实例共享的属性和方法。即我们不必在构造函数中定义对象实例的信息,而将这些信息直接添加到原型对象中。

    function Person() {}
    Person.prototype.name = "Dobby";
    Person.prototype.age = 5;
    Person.prototype.sayName () = function() {
        alert(this.name);
    }
    var person1 = new Person();
    var person2 = new Person();

    优点:对象的所有属性和方法由所有实例共享,即实例访问都是同一组属性和方法;

    缺点:首先,所有实例在默认情况下取得相同的属性值;最大的问题是当对象包含引用值的属性(如数组)时,如果一个实例的属性值数组发生变化,即该数组的变化将反应在所有的实例上。

    四、组合使用构造函数模式和原型模式

    构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype = {
        constructor: Person,
        sayName: function() {
            alert(this.name);
        }
    }

    优点:每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度的节省了内存,另外,这种模式还支持向构造函数传递参数;

    缺点:没有把全部信息封装在构造函数中。

    五、动态原型模式

    可以通过检查某个应该存在的方法是否有效,来动态决定是否需要初始化原型。

    function Person(name, age) {
        this.name = name;
        this.age = age;

        if( typeof this.sayName != "function") {
            Person.prototype.sayName = function() {
                alert(this.name);
            }
        }
    }

    优点:可以将全部信息封装在构造函数中;

    缺点:暂无。

    六、寄生构造函数模式

    基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。

    function Person(name, age){
         var o = new Object();
         o.name = name;
         o.age = age;
         o.sayName = function() {
            alert(this.name);
         }
         return o;
    }
    var friend = new Person("Dobby", 5);

    除了使用 new 操作符并把使用的包装函数叫构造函数之外,这个模式和工厂模式其实是一模一样的。

    七、稳妥构造函数模式

    没有公共属性,而且其他方法也不引用 this 对象。
    与寄生构造函数有两点不同:
    1. 新创建对象的实例方法不引用 this
    2. 不使用 new 操作符调用构造函数

    function Person(name, age) {
        var o = new Object();
        // 定义私有变量和函数

        // 添加公有方法
        o.sayName = function() {
            alert(name);
        }
        return o;
    }
    var friend = Person("Dobby", 5);

    其安全性使它非常适合在某些安全执行环境下使用。

    相关文章

      网友评论

          本文标题:JS之创建对象的方式及其优劣

          本文链接:https://www.haomeiwen.com/subject/cfxbkqtx.html