引言:
没有绝对优秀的构造函数的方法,每一种方法都有他们的优缺点,我们需要考虑的是知道他们的应用场景,合理的使用他们,从而达到自己的要求。

1.Object构造函数模式
使用方式:先创建空对象,再添加属性/方法
适用场景:起始时不确定对象内部的数据
缺点:语句太多

var person = new Object()
person.age = 15
person.name = 'Bob'
person.run = function () {
  console.log('run');
}

2.对象字面量
使用方式:使用{}创建对象,同时指定属性/方法
适用场景:起始时对象内部数据确定
缺点:如果创建多个对象,有重复代码

var person = {
  name: 'Bob',
  age: 15,
  run() {
    console.log('run');
  }
}
var person2 = {
  name: 'Jack',
  age: 13,
  run() {
    console.log('run');
  }
}

3.工厂模式
使用方式:通过工厂函数动态创建对象并返回
适用场景:需要创建多个对象
缺点:对象没有具体的类型,都是Object类型

function createPerson(age, name) { //返回一个对象的函数==》工厂函数
  var obj= {
    name: name,
    age: age,
    run() {
      console.log('run');
    }
  }
  return obj
}

var p1 = createPerson(14,'Bob')
var p2 = createPerson(15,'Jack')
console.log(p1 instanceof createPerson) //false

4.自定义构造函数模式
使用方式:自定义构造函数,通过new创建实例对象
适用场景:需要创建多个类型确定的对象
缺点:每个对象都有相同的数据,浪费内存

function Person(age, name) {
  this.name = name
  this.age = age
  this.run = function () {
    console.log('run');
  }
}

var p1 = new Person(15, 'Bob')
console.log(p1 instanceof Person)//true

function Dog(age, name) {
  this.name = name
  this.age = age
  this.eat = function () {
    console.log('eat');
  }
}
var d1 = new Dog(3, 'JoJo')
console.log(d1 instanceof Dog)//true

每一个实例上都有相同的方法,但是每一次创建却需要再创建一次。

var p1 = new Person(15, 'Bob')
var p2 = new Person(13, 'Jack')
console.log(p1, p2)


5.构造函数+原型的组合
使用方式:自定义构造函数,属性在函数中初始化,方法添加到原型上
适用场景:需要创建多个类型确定的对象

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

Person.prototype.setName = function (name) {
  //这里的this是指向每一个实例化后的对象
  this.name = name
}

现在他的原型上都有一个共有的方法

var p1 = new Person(15, 'Bob')
var p2 = new Person(13, 'Jack')
console.log(p1, p2)


6.动态原型模式
动态原型函数模式把所有信息都封装在了构造函数中,在构造函数中初始化原型,又保持了同时使用构造函数和原型的优点。

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

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

var p = new Person(15, 'Bob')
console.log(p);


如果不用if判断的方式直接在原型上添加方法,那么每一次new一个实例对象的时候都会去重写原型,浪费内存空间,而如果加了判断那么在原型只会在第一次实例话对象的时候就生成了,以后每一次new实例均不会再重写原型对象。

7.稳妥构造函数模式
所谓稳妥对象,指的是没有公共属性,而且其方法也不引用this的对象。稳妥对象最适合在一些安全环境中。

function Person(age, name) {
  var o = new Object()
  job = 'kuli' //私有属性
  o.sayName = function () { //共有函数
    console.log(name);
  }
  o.sayJob = function () {
    console.log(job);
  }
  return o
}

var p = new Person(15, 'Jack')
console.log(p);
console.log(p.sayName(), p.sayJob());//Jack kuli
console.log(p.name)//undefined 只能通过调用sayName方法查看name属性

8.es6 class
与组合构造函数非常相似,语法更加精炼简洁。

class Person {
  constructor(age, name) {
    this.age = age
    this.name = name
  }
  setName(name) {
    this.name = name
  }
}

var p1 = new Person(13, 'Bob')
p1.setName('Jack')
console.log(p1);

更多推荐

构造函数的8种方式