关于JavaScript闭包:为何构造函数内的temp变量可替代实例使用?
为什么Pizza构造函数内部的temp变量能被当作实例本身来使用?
嘿,这个问题问到点子上了!核心要搞懂两个关键知识点:new操作符的返回规则,以及闭包的特性,咱们慢慢拆解清楚:
1. new操作符的特殊逻辑
当你用new Pizza()调用构造函数时,JavaScript本来会默认完成这几件事:
- 创建一个空对象,让这个对象和构造函数的原型关联
- 把构造函数里的
this指向这个新对象 - 执行构造函数内部的代码
- 默认返回这个新创建的对象
但!如果构造函数主动返回了一个对象类型的值(比如你代码里的temp),那new操作符就会直接把这个返回的对象作为最终的实例结果,而不是它默认创建的那个this对象。
所以你的pizzaA其实就是构造函数内部的temp对象本身,而不是包含temp属性的另一个对象——这就是为什么你不用pizzaA.temp.getToppings(),直接pizzaA.getToppings()就能调用的原因!
2. 闭包让getToppings能访问内部变量
再说说为什么getToppings能返回正确的toppings值:getToppings是构造函数内部定义的函数,它属于闭包——闭包的核心特性就是,内部函数可以保留对外部作用域变量的引用,哪怕外部函数(也就是Pizza构造函数)已经执行完毕。
所以当你通过pizzaA.getToppings()调用时,这个函数依然能访问到构造函数里的toppings变量,自然就能返回3啦。
结合你的代码再梳理一遍
咱们把关键步骤标出来,看得更清楚:
var Pizza = function () { var crust = 'thin'; var toppings = 3; // 这个函数是闭包,保留了对toppings的引用 var getToppings = function () { return toppings; }; // 创建一个空对象 var temp = {}; // 把闭包函数挂载到temp上 temp.getToppings = getToppings; // 返回temp对象,new操作符会把它直接赋值给pizzaA return temp; }; var pizzaA = new Pizza(); // pizzaA就是temp对象本身,直接调用它的getToppings方法即可 console.log(pizzaA.getToppings()); // 输出3
总结一下:你之前误以为temp是实例的一个属性,但实际上它就是实例本身——因为构造函数主动返回了它,new操作符就把它当成了最终的实例。而闭包则保证了getToppings能拿到构造函数内部的toppings变量。
内容的提问来源于stack exchange,提问作者Edgar Sugar Doughnut Jin
相关产品推荐
相关产品推荐

