将函数放入 javascript 对象中是一种好习惯吗? [复制]
Posted
技术标签:
【中文标题】将函数放入 javascript 对象中是一种好习惯吗? [复制]【英文标题】:Is it a good practice to put functions in is javascript objects? [duplicate] 【发布时间】:2019-11-20 13:30:55 【问题描述】:我做了一个构造函数,并打算做大量的对象。
function Cat(name)
this.name = name;
this.meow = function ()
...
...
说,meow() 函数很长。如果我创建了很多猫或者 javascript 会处理它,它会成为内存问题吗?在这种情况下,创建静态函数而不是对象内的函数更好吗?
【问题讨论】:
通常你将函数放在原型中,而不是放在每个实例中。 您是否有意避开modern JS's dedicated support for classes via theclass
keyword?使用它们会消除这种担忧; JS 解释器应该自动使用任何最有效的解决方案,而不必担心您是否意外地为每个实例创建了一个闭包(碰巧,它基本上是为您创建一个带有每个方法的单个副本的原型)。
meow
函数是否冗长无关紧要。它为每个实例创建一个新的函数对象,如果您有无数个实例,这将成为一个问题。主体的代码大小不会影响用于这些函数对象之一的内存。
@ShadowRanger 不知道你说的“它基本上是用每个方法的一个副本创建一个原型”是什么意思?
@Bergi:其他答案中给出的解决方案是手动将函数附加到Cat.prototype
,例如Cat.prototype.meow = function() ;
是现代class
语法在幕后自动执行的操作。该函数创建一次,并且单个副本绑定到原型。当您尝试查找 instance.meow
时,Cat
的每个实例都会找到该单个副本。
【参考方案1】:
最好使用原型。
function Cat(name)
Cat.prototype.meow = function();
大多数现代引擎(包括 chrome 的 V8)会将对象创建优化为可重用路径,而如果使用 this.meow,则在每次实例化时定义自定义隐藏路径。
转为微优化会更好吗?这实际上取决于您的实施和环境。
有关原型提高性能的方式的更详尽说明,请参阅 V8 开发人员 Toon Verwaest 提供的中等解释,Setting up prototypes in V8。
【讨论】:
"如果使用 this.meow,那么在每个实例化时都会定义一个自定义隐藏路径" - 这听起来不太对。我是不是误解了你的意思? @Bergi - 我不确定?让我展开,你可以告诉我。使用this.meow
附加函数将成为过渡对象的一部分,它使用隐藏类创建一个完整的隐藏路径,该路径在使用new Cat()
时被发现并创建。使用原型将为该原型对象创建一个特定的隐藏类,该对象可以重复使用,并且在使用new Cat()
时不需要每次都创建。
所有Cat
对象的过渡路径和隐藏类都是一样的,不需要每次调用构造函数时都创建,这就是系统的重点。
@Bergi - 我不相信 Cat 类的所有实现都是一样的。转换路径将与之前对构造函数的调用相同,但是,它与使用this.
附加属性的修改版本不同。我相信每次都需要发现它们,因为它们不是使用构造函数本身添加的,而是在创建对象后执行的函数中添加的。这是使用原型(使用自定义路径进行初始化,而不是每次都需要修改)之间的核心区别。
我们在这里讨论的是相同的代码吗? Cat
类只有一个实现。所有实例化都将遵循相同的隐藏类转换路径(在第一次调用时创建),而构造函数初始化属性 - 属性值是函数还是其他东西绝对无关紧要。不确定“不是在构造函数本身中,而是在创建对象后执行的函数中”是什么意思。这些方法不创建新属性?【参考方案2】:
您可以在 Cat 的原型中添加功能。这样,对 meow 的任何调用都将引用相同的函数。
Cat.prototype.meow = function() ;
【讨论】:
【参考方案3】:简答:不贵。 长答案:研究函数式编程与面向对象编程。使用 JavaScript 函数式编程将允许您做各种巧妙的事情,例如:
function add(a, b)
return a + b;
function subtract5(a)
return a - 5;
//You can pass functions into functions like: subtract5(add(3, 3)) = 1;
然后,您还可以使用函数式编程语言通过 find、forEach、map、reduce 等函数让您的生活更轻松,它需要一个条件函数来将其应用于您正在使用的数组...例如:
function condition(x)
return x.id == 2;
var users = []
users.push(
id:1,
name:"Bob"
);
users.push(
id:2,
name:"Dan"
)
// users.find(condition).name is equal to Dan
//The condition function can be a lot of things which is why it's so powerful
另一个很好的例子(我在一个有很多内部函数的 javascript 游戏中使用了这种格式,它没有显示任何负面影响 性能)
var Cat = function(param)
var self = ;
self.name = param.name;
self.age = param.age;
self.birthday = function()
self.age++;
return self;
var youngCat = new Cat(name: "Ginger", age: 2);
youngCat.birthday();
【讨论】:
forEach
不是函数式编程。我真的不明白这是如何回答这个问题的,你的 Cat
构造函数仍然存在与 OP 代码相同的问题。
我的“猫”示例没有问题。如上所述,我在 Node.Js 中制作了一个非常强大的 JavaScript 游戏,每个元素(玩家、物品等)都使用了该系统。这是一个 MOBA,所以有很多玩家在同一个领域,我没有看到性能问题。另外,我说的是array.forEach 而不是foreach(...)。这里有一篇文章解释得很好:medium.com/@eliaai/…
“很多玩家”是什么意思,几百?是的,我说的是数组方法。仅仅采用回调函数并不能使某些东西发挥作用。
也许我措辞错误。我的意思是显然有一个成本,我只是说它非常小而且不明显,并且不会导致 OP 的计算机崩溃,因为他创建了 10000 只猫。为了回答你的问题,一次有 10 名玩家(MOBA 就像英雄联盟一样,它是 5v5)以上是关于将函数放入 javascript 对象中是一种好习惯吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
将 UICollectionView 和 UITableView 放在 iOS 的 UIScrollView 中是一种好习惯吗?
将嵌入式码头和 GRPC 服务器运行在同一个 JVM 中是一种好习惯吗?
将所有环境(dev uat prod)的 jar 和配置打包在一个 zip 中是一种好习惯吗?