JS的new做了什么?

270 阅读2分钟
  • 1.创建临时对象/新对象;
  • 2.绑定原型
  • 3.指定this = 临时对象
  • 4.执行构造函数
  • 5.返回临时对象

JS的new到底是做什么的?

制造士兵游戏

var 士兵 = {
  ID: 1, // 用于区分每个士兵
  兵种:"美国大兵",
  攻击力:5,
  生命值:42, 
  行走:function(){ /*走俩步的代码*/},
  奔跑:function(){ /*狂奔的代码*/  },
  死亡:function(){ /*Go die*/    },
  攻击:function(){ /*糊他熊脸*/   },
  防御:function(){ /*护脸*/       }
}

兵营.制造(士兵)
  • 上面属性中行走、奔跑、死亡、攻击、防御,这5个动作,对于每个士兵是一样的,只需要各自引用同一个函数就可以了。如果创建100个士兵的话,没必要重复引用;
  • 只有ID和生命值需要创建100次;

用原型链解决这个问题

用原型链可以解决重复创建的问题:我们先创建一个「士兵原型」,然后让「士兵」的 proto 指向「士兵原型」

var 士兵原型 = {
  兵种:"美国大兵",
  攻击力:5,
  行走:function(){ /*走俩步的代码*/},
  奔跑:function(){ /*狂奔的代码*/  },
  死亡:function(){ /*Go die*/    },
  攻击:function(){ /*糊他熊脸*/   },
  防御:function(){ /*护脸*/       }
}
var 士兵们 = []
var 士兵
for(var i=0; i<100; i++){
  士兵 = {
    ID: i, // ID 不能重复
    生命值:42
  }

  /*实际工作中不要这样写,因为 __proto__ 不是标准属性*/
  士兵.__proto__ = 士兵原型 

  士兵们.push(士兵)
}

兵营.批量制造(士兵们)

JS之父的关怀

JS之父创建了new关键字,可以让我们能少些代码

image.png

只要你在士兵前面使用 new 关键字,那么可以少做四件事情:

  1. 不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);\

  2. 不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);\

  3. 不用 return 临时对象,因为 new 会帮你做;\

  4. 不要给原型想名字了,因为 new 指定名字为 prototype。

用new来写

function 士兵(ID){
  this.ID = ID
  this.生命值 = 42
}

士兵.prototype = {
  兵种:"美国大兵",
  攻击力:5,
  行走:function(){ /*走俩步的代码*/},
  奔跑:function(){ /*狂奔的代码*/  },
  死亡:function(){ /*Go die*/    },
  攻击:function(){ /*糊他熊脸*/   },
  防御:function(){ /*护脸*/       }
}

// 保存为文件:士兵.js

然后是创建士兵(加了一个 new 关键字):

var 士兵们 = []
for(var i=0; i<100; i++){
  士兵们.push(new 士兵(i))
}

兵营.批量制造(士兵们)