Mir*_*ode 4 javascript methods prototype
阅读完这篇文章https://www.toptal.com/javascript/es6-class-chaos-keeps-js-developer-up以及随后的“JavaScript:优秀部分”后,我将致力于成为一名更好的 JavaScript 开发人员。然而,我仍然有一个问题。我通常实现这样的方法:
function MyClass(){
this.myData = 43;
this.getDataFromObject = function(){
return this.myData;
}
}
MyClass.prototype.getDataFromPrototype = function(){
return this.myData;
}
var myObject = new MyClass();
console.log(myObject.getDataFromObject());
console.log(myObject.getDataFromPrototype());
Run Code Online (Sandbox Code Playgroud)
我的假设是,整篇文章的基础是 getDataFromObject 更快(在调用期间,而不是在对象创建期间),因为它保存了对原型的间接访问,但它的内存效率也较低,因为每个对象都有一个自己的函数对象实例。如果这已经是错误的,请纠正我,你可能可以停止阅读这里。
否则:文章和书都推荐这样的风格:
function secretFactory() {
const secret = "Favor composition over inheritance [...]!"
const spillTheBeans = () => console.log(secret)
return {
spillTheBeans
}
}
const leaker = secretFactory()
leaker.spillTheBeans()
Run Code Online (Sandbox Code Playgroud)
(引自文章,书中还没有ES6,但思路是相似的)
我的问题是这样的:
const leaker1 = secretFactory()
const leaker2 = secretFactory()
console.log(leaker1.spillTheBeans === leaker2.spillTheBeans) // false
Run Code Online (Sandbox Code Playgroud)
我不是最想避免每个对象都有每个方法自己的实例吗?它在这里可能微不足道,但如果spillTheBeans更复杂并且我创建了无数个对象,每个对象都有一万二万个其他方法?
如果是这样,“好的部分”解决方案是什么?我的假设是:
const spillStaticBeans = () => console.log("Tabs rule!")
const spillInstanceBeans = (beans) => console.log(beans)
function secretFactory() {
const secret = "Favor composition over inheritance [...]!"
return{
spillStaticBeans,
spillInstanceBeans: () => spillInstanceBeans(secret)
}
}
const leaker1 = secretFactory()
const leaker2 = secretFactory()
leaker1.spillStaticBeans()
leaker2.spillInstanceBeans()
console.log(leaker1.spillStaticBeans === leaker2.spillStaticBeans) // true
console.log(leaker1.spillInstanceBeans === leaker2.spillInstanceBeans) // false
Run Code Online (Sandbox Code Playgroud)
OverflowInstanceBeans 方法仍然不同,因为每个实例都需要自己的闭包,但至少它们只是包装对包含所有昂贵内容的同一函数对象的引用。
但现在我必须将每个方法名称写两到三遍。更糟糕的是,我用公共的spillStaticBeans 和spillInstanceBeans 函数弄乱了命名空间。为了缓解后者,我可以编写一个元工厂模块:
const secretFactory = (function(){
const spillStaticBeans = () => console.log("Tabs rule!")
const spillInstanceBeans = (beans) => console.log(beans)
return function() {
const secret = "Favor composition over inheritance [...]!"
return{
spillStaticBeans,
spillInstanceBeans: () => spillInstanceBeans(secret)
}
}
}())
Run Code Online (Sandbox Code Playgroud)
这可以像以前一样使用,但现在这些方法隐藏在闭包中。然而,这有点令人困惑。使用 ES6 模块,我还可以将它们保留在模块范围内而不导出它们。但这是要走的路吗?
或者我总体上是错误的,JavaScript 的内部函数表示处理了这一切,并且实际上没有问题?
我的假设是整篇文章的基础是
getDataFromObject调用速度更快,getDataFromPrototype因为它保存了对原型的间接访问
不会。引擎非常擅长优化原型间接。对于同一类的实例,总是instance.getDataFromPrototype解析为相同的方法,引擎可以利用这一点。有关详细信息,请参阅这篇文章。
我不是最想避免每个对象都有每个方法自己的实例吗?在这里可能微不足道
是的。在大多数情况下,它实际上是微不足道的。因此,使用您喜欢的任何风格来编写您的对象和方法。仅当您实际测量了性能瓶颈时,才需要重新考虑创建许多实例的情况。
使用 ES6 模块,我还可以将它们保留在模块范围内而不导出它们。但这是要走的路吗?
是的,这是一个明智的解决方案。但是,没有充分的理由提取spillInstanceBeans到静态范围,只需将其保留在原来的位置即可 - 无论如何,您都必须创建一个闭包secret。
| 归档时间: |
|
| 查看次数: |
211 次 |
| 最近记录: |