javascript中创建对象的几种方式

54 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情

js中创建对象的方式很多,我总结了10种供参考,欢迎大家订正或者补充啊。

  1. new Object()
    这种方式实际中使用的不多,缺点是,步骤比较多,显得有点繁琐。

  2. 字面量
    var obj = {}; 如果要反复创建多个对象,代码会冗余。

  3. 工厂函数方式

function createPerson(name, age){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.say = function(){console.log(this.name);}
    
    return o;
}

var p1 = createPerson('Tom', 20);

这种工厂的方式,封装了详细的创建对象的过程。 缺点,本质还是Object(),将来无法根据对象原型对象准确判断对象的类型。

  1. 构造函数
    缺点:如果构造函数中包含方法,则重复创建,浪费内存。

  2. 原型对象

function Person(){}

Person.prototype.name = '666';

let p1 = new Person();
p1.name = 'Tom';

let p2 = new Person();
p2.name = 'Jerry';

console.log(p1, p2);

缺点: 步骤繁多。

  1. 混合模式 先创建完相同的对象,再给子对象添加个性化属性。
function Person(name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.say = function(){
   console.log(this.name);
}

let p1 = new Person("Tom", 20);
let p2 = new Person("Jerry", 21);

缺点: 不符合面向对象封装的思想。

  1. 动态混合 先创建完相同的对象,再给子对象添加个性化属性。
function Person(name, age){
  this.name = name;
  this.age = age;

  if(Person.prototype.say === undefined){
     Person.prototype.say = function(){
        console.log(this.name);
     }
  }
}

let p1 = new Person("Tom", 20);
let p2 = new Person("Jerry", 21);

缺点:语义不符,if只在创建第一个对象时才有意义。

  1. 寄生构造函数
    构造函数里调用其他的构造函数。
function Person(name, age){
  this.name = name;
  this.age = age;

  if(Person.prototype.say === undefined){
     Person.prototype.say = function(){
        console.log(this.name);
     }
  }
}

function Student(name, age, className){
   var p = new Person(name, age);
   p.className = className;
    
   return p;
}

let p1 = new Student("Tom", 20, "1");

缺点:可读性差。

  1. ES6 class 用class包裹原构造函数 + 原型对象方法。
    注意:class写法中定义的原型对象方法,和ES5写法中定义个原型对象方法,功能是一样的,但是也不是完全一模一样。class写法中定义的原型对象不可枚举。

    注意:浏览器中显示的"[[Prototype]]",指的是,这个属性是内部属性。

  2. 稳妥构造函数 闭包,不用this,不用new,安全可靠。

function Person(name, age){
    let p = {};
    
    p.getName = function(){return name;}
    p.getAge = function(){return age;}
  
    return p;
}

缺点,使用了闭包,容易造成内存泄漏。