for循环中new的对象什么时候被回收_你真的了解JS⾥的new
吗?
前⾔
我们常常喜欢⽤new关键字去创建⼀些对象如new Vue(),但是这个关键字的背后究竟做了什么其实没太多⼈去关注。
想象我们是苹果公司,要⽣产30部iPod,规定: 每台iPod都会有⾃⼰的ID 每台iPod都是⼀样的制造商:Apple * 每台iPod的功能都是⼀样的(函数⼀样)
特定物
let iPod= {
// 制造商不会变
manufacturer: 'Apple',
// 播放⾳乐
play: function () { },
// 暂停
pau: function () { },
// 继续播放
resume: function () { }
}关于月亮的古诗100首
好了,现在我们开始⽣产吧。
简单⽣产
要⽣产那么多iPod,那就循环30次吧。每次循环都创建⼀个对象,将这个对象加⼊到数组⾥就⾏了。
let box = []
let iPod
for (let i = 0; i < 30; i++) {
iPod= {
// 每次都改变 ID
id: i,
/
/ 制造商不会变
manufacturer: 'Apple',
// 播放⾳乐
play: function () {},
// 暂停
pau: function () {},
// 继续播放
resume: function () {}
}
box.push(iPod)
}
Manufacturer.deliver(box)
但是,这⾥有⼀个问题:每次都会新创建play(),pau(),resume()这些函数,manufacturer的值也是⼀样,没必要重新建。
多少号过年
使⽤原型改进
使⽤原理链,我们可以将上⾯说到的共有函数,属性放在⼀个共有对象⾥,然后⽤iPod.__proto__指向这个iPodCommon不就好了吗?所以现在代码可以改写成这样:
let box = []
let iPod
let iPodCommon = {
不同的英语// 制造商不会变
manufacturer: 'Apple',
// 播放⾳乐
日本出国留学play: function () {},
qq音乐图标
// 暂停
pau: function () {},
// 继续播放
resume: function () {}
}
for (let i = 0; i < 30; i++) {
iPod= {
// 每次都改变 ID
id: i,
}
iPod.__proto__ = iPodCommon
box.push(iPod)
}
Manufacturer.deliver(box)
这样就好多了,省了很多空间。但是这个iPod对象的代码有点太分散了,跟for循环耦合在⼀起了。学习重构时听得最多的⼀句就是重复代码最好⽤函数包起来,所以我们可以试着传⼊要改变的属性(ID)⽤函数来返回iPod对象。,
函数返回对象
我们可以⽤⼀个函数返回iPod对象,这样就不⽤每次都在for循环⾥去定义对象了。
function iPod(id) {
let tempObj = { }
// ⾃有属性
最美的姿态
tempObj.id = id
// 共有属性,函数
tempObj.__proto__ =
return tempObj
}
< = {
// 制造商不会变
manufacturer: 'Apple',
// 播放⾳乐
play: function () {},
// 暂停
pau: function () {},
// 继续播放
resume: function () {}
}
// 保存为 iPod.js ⽂件
然后在创建时候引⼊这个⽂件,再去⽣成iPod。
let box = []
for (let i = 0; i < 30; i++) {
box.push(iPod(i))
}
Manufacturer.deliver(box)
大学生开学有没有感觉这样清爽了很多?我们将所有有关iPod的逻辑都放在⼀个⽂件⾥,这样就和主⽂件完全解耦了。
new
上⾯是很清爽,但是每次都要写创建⼀个临时对象好⿇烦。这时候JS的new就上场了,它的作⽤如下: 1. 帮你创建临时对象tempObj,函数⾥的this绑定为这个tempObj 2. 统⼀共有属性所在对象的名字叫prototype⽽不是comon 3. 帮你完成原型的绑定 4. 帮你返回临时对
象tempObj 现在iPod.js⽂件可以写成这样
function iPod(id) {
this.id = id
}
// 共有属性
iPod.prototype = {
/
/ 制造商不会变
manufacturer: 'Apple',
// 播放⾳乐
play: function () {},
// 暂停
pau: function () {},
// 继续播放
resume: function () {}
}
// 保存为 iPod.js ⽂件
使⽤new再次⽣产iPod
let box = []
for (let i = 0; i < 30; i++) {
box.push(new iPod(i))
}
Manufacturer.deliver(box)
这就是new的由来,不过是⼀种语法糖,和Java⾥⾯的new是完全不⼀样的东西,希望⼤家不要混为⼀谈。当然了,最后的这个iPod函数也构造函数。
就成了我们所说的构造函数