javascript原型和内存[重复]

Posted

技术标签:

【中文标题】javascript原型和内存[重复]【英文标题】:javascript prototypes and memory [duplicate] 【发布时间】:2016-05-03 20:02:50 【问题描述】:

我正在参加新兵训练营,今天在课堂上发表了以下声明:

"一般来说,在使用构造函数时,如果您希望每个对象都可以访问函数,请将函数放在原型中,而不是放在原始构造函数中。这样可以节省内存,因为而不是创建每次调用对象时都会创建一个新函数,每个对象在使用该函数时都会简单地引用原型。”

谁能解释/验证?

【问题讨论】:

声明有效 这不是一个合适的问题,因此您可能会被关闭。但原因也是为了维护。在显着使用额外的内存之前,需要有许多这样的方法或实例。 为什么这不是一个合适的问题? 简化,从对象中获取值的工作方式有点像这样:让o 成为您尝试访问属性p 的对象。 1.如果o没有自己的属性p,让o = Object.getPrototypeOf(o);返回1。否则2.如果oundefined返回未定义。 3.返回o的自有属性p的值。 【参考方案1】:

"一般来说,在使用构造函数的时候,如果你要 希望每个对象都可以访问一个函数,将该函数放入 原型,而不是在原始构造函数中。这 将节省内存,因为不是每次都创建一个新函数 对象的调用,每个对象将简单地引用 使用该函数时的原型。”

这句话是真的。

prototype 的一个重要特征是它是一个在该类型对象的所有实例之间共享的单个对象。

因此,原型上的任何方法都在该类型对象的所有实例之间共享。这种单一原型对象的“共享”是一种内存有效的方式,所有对象都可以访问一组通用的方法/属性。

如果你像这样在构造函数中初始化方法:

function MyConstructor() 
    this.print = function() 
        // code here
    

然后,每次调用构造函数(对象的每个新实例)都会创建一个新的函数对象并分配一个新的自己的属性,这确实会使用更多的内存。


现在,使用更多内存是否真的相关是一个单独的问题。除非你有很多这些类型的对象,否则它不会使用更多的内存。

有些人(Douglas Crockford 就是其中之一)提倡一种不使用原型的特定对象定义编码方法,他认为额外使用内存与他的方法的好处相比是无关紧要的。由于 ES6 中新的“类”语法仍在使用原型(在幕后),看来他的观点还没有被那些指导语言未来的人所接受。

如果您想要只有实例的某些方法可以访问并且不能从外部世界访问的“私有”成员变量,那么您可能希望在构造函数中将这些成员变量声明为局部变量并分配任何方法您希望能够访问构造函数中的那些“私有”成员变量(您不能将它们放在原型上)。您可以在his writeup here 中查看 Crockford 关于如何制作“私有”实例变量的文章。这在变量的隐私(或有时安全)很重要的某些情况下非常有用。

有关 Crockford 对原型的一些看法,请参阅this video(转到视频中的 31:30 点,然后是之后的 36:00 点)。

【讨论】:

"似乎这种观点并没有被那些指导语言未来的人所接受" - 好吧,原型方法还有其他好处,而且两者都有接受视图/模式。这取决于您需要/喜欢什么,两者都是可行的。 ES6 在语法上都简化了这两种方式。 @Bergi - 我的观点是,如果那些指导语言未来的人认为不将方法放在原型上总是甚至通常更好,他们就不会这样做,所以定义使用class 关键字的对象将这些方法放在原型上。显然,他们打算长期继续支持原型,并且不会以任何方式将语言从原型中移开。 ES6 如何简化了声明对象的不同方式? 是的,javascript 将(并且可以)肯定不会放弃基于原型的对象模型,但它仍将是一种支持多种做事方式的多范式语言。 Crockfords 模式在语法上一直很简单,有人可能会争辩说,解构和属性简写使其更易于使用。

以上是关于javascript原型和内存[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在构造函数与原型中声明javascript对象方法[重复]

访问 Javascript 对象原型 [重复]

在 JavaScript 原型函数中保留对“this”的引用 [重复]

在类原型函数中复制javascript数组[重复]

使用javascript循环读取JSON数字数组[重复]

使用javascript将UNIX TIMESTAMP转换为日期[重复]