如何改造工厂函数的方法,移除其中的`this`关键字?
不用
this实现对象方法访问属性的方案 嘿,这个问题其实很好解决——利用JavaScript的闭包特性就行,根本不需要依赖this来访问对象的属性。下面给你几种具体的实现方案:
方案1:直接引用工厂函数的参数
因为返回的totalCost函数是工厂函数planeCreator内部定义的,它可以直接捕获并访问工厂函数的参数,这就是闭包的作用:
'use strict' function planeCreator(a, b, c) { return { manufacturer: a, numberOfEngines: b, costPerEngine: c, totalCost: function() { // 直接使用工厂函数的参数b(发动机数量)和c(单台成本) return b * c; } } } let b17 = planeCreator('B-17', 4, 25000); document.querySelectorAll('.output')[0].textContent = b17.totalCost(); // 输出100000
这种方式最直接,不需要额外的变量定义,完全利用闭包的特性实现。
方案2:提前定义清晰的变量(可读性更好)
如果觉得直接用参数名b、c不够直观,可以先把参数赋值给语义化的变量,再让totalCost引用这些变量:
'use strict' function planeCreator(a, b, c) { // 定义和对象属性同名的变量,增强可读性 const numberOfEngines = b; const costPerEngine = c; return { manufacturer: a, numberOfEngines, costPerEngine, totalCost: function() { return numberOfEngines * costPerEngine; } } } let b17 = planeCreator('B-17', 4, 25000); document.querySelectorAll('.output')[0].textContent = b17.totalCost();
这种方式代码可读性更高,后续如果要调整属性逻辑,变量名也更清晰。
方案3:使用箭头函数(本质还是闭包)
箭头函数本身没有自己的this,它会继承外层作用域的变量,所以也可以用来实现:
'use strict' function planeCreator(a, b, c) { return { manufacturer: a, numberOfEngines: b, costPerEngine: c, totalCost: () => { // 同样利用闭包访问工厂函数的参数 return b * c; } } } let b17 = planeCreator('B-17', 4, 25000); document.querySelectorAll('.output')[0].textContent = b17.totalCost();
注意:这里箭头函数的优势不是this,而是它本身就能访问外层作用域的变量,和普通函数的闭包效果一致,只是写法更简洁。
核心原理
以上所有方案的核心都是闭包:当函数(比如totalCost)在其定义的作用域之外被调用时,它仍然能访问定义时所在作用域的变量(比如工厂函数的参数或内部变量)。这就绕过了对this的依赖,直接通过闭包获取需要的属性值。
内容的提问来源于stack exchange,提问作者DR01D




