七种创建对象方法的简单理解

295 阅读3分钟

1.工厂模式

  • 将创建普通对象的方法封装成一个函数,并返回这个对象,每次创建相似对象只需要调用函数即可
function creatP(name){  
    let obj = new Object();  
    obj.name = name;  
    return obj;
}
let person = creatP('张三');
console.log(person.name);   //张三

优点:

  • 可以通过此方法创建多个相似对象

缺点:

  • 如果其中出现一个错误,全部都会崩溃
  • 不能创建特定类型的对象,例如Array...

2.构造函数模式

  • 利用new函数的特性,实例会拥有构造函数的属性,并独立于构造函数
function Person(name){  
    this.name = name;
    this.sayName = sayName;
}
function sayName(){
    console.log(this.name)
}
let person = new Person('张三');
console.log(person.name);   //张三

优点:

  • 构造函数可以创建特定类型的对象:Array,Object
  • 没有显式的创建对象(使用Object或{})
  • 直接将方法和属性赋给this对象
  • 没有return方法

缺点:

  • 构造函数的方法可以在全局作用域中定义,但这个方法只能被构造函数调用,有悖于全局作用域的定义

3.原型模式

let Person = function(){
    Person.prototype.name='张三';
    Person.prototype.sayName=(name)=>{
        console.log(name)
    }
}
let person = new Person();
person.sayName(person.name) //张三

优点:

  • 解决了构造函数方法的问题

缺点:

  • 所有实例会默认获得最开始设置的初始值
  • 对于引用类型的属性值,一个实例改变,会影响其他实例
let Person = function(){
    Person.prototype.names=['张三','李四'];
}
let person1 = new Person();
let person2 = new Person();

person1.names.push('王五'); 
console.log(person2.names); //[ '张三', '李四', '王五' ]

4.组合使用构造函数和原型模式

  • 如字面意思所言,使用构造函数和原型模式共同创建对象
    • 使用构造函数模式定义实例属性
    • 使用原型模式定义方法共享属性
function Person(name){
    this.name = ['张三', '李四'];
}
Person.prototype.name = '张三';
Person.prototype.sayName = function(){
    console.log(this.name);
}
let person1 = new Person();

person1.sayName();   //[ '张三', '李四' ]

5.动态原型模式

  • 简单来说就是更加灵活地使用原型模式,使用判断来分辨是否需要向原型链中添加属性或方法
function Person(){
    this.name = '张三';
    if(!(this.sayName instanceof Function)){    //如果没有sayName方法则向原型链添加方法
        Person.prototype.sayName = function(){
            console.log(this.name);
        }
    }
}

let person1 = new Person();
person1.sayName();  //张三

优点:

  • 按需添加,节省资源

注:不要每个属性都判断造成过多的添加'if',也不要重写prototype,导致原型链崩溃

6.寄生构造函数模式(不建议)

  • 类似普通的工厂模式,主要使用return方法重写调用构造函数时返回的值
function Person(){
    let names = new Array();
    names.push.apply(names,arguments);
    return names;
}

let person1 = new Person('张三');
console.log(person1)

缺点:

  • 与构造函数方式相同,不能通过instanceOf方法判断类型

7.稳妥构造函数模式(不建议)

  • 与普通构造函数不同的是,构造函数中不使用this,也不使用new操作符,适合在某些安全执行环境中使用 --- ‘ADsafe’、‘Caja’
function Person(name,age){
    let o = new Object();
    o.sayName = function(){
        console.log(name,age);
    }
    return o;
}

let per1 = Person('张三','18');
per1.sayName(); //张三 18

缺点:

  • 完全封闭,除了内置方法外没有访问其中数据的途径

借鉴:《JavaScript高级程序设计》 + 网上查找 + 自己的理解

如有错误,希望提出

希望大家都能早日拿到心仪的offer,加油,共勉