admin管理员组文章数量:1401947
Let's say I want to create an array of Person
using a random data library.
I could do something like
import {generateRandom} from 'someLib'
let people = []
function getPerson() ({
name: generateRandom.string()
age: generateRandom.number()
})
for (let i = 0; i < 10; i++) {
people.push(getPerson())
}
But I could also do something like
import {generateRandom} from 'someLib'
class Person {
constructor() {
this.name = generateRandom.string(),
this.age = generateRandom.number()
}
}
let people = []
for (let i = 0; i < 10; i++) {
people.push(new Person())
}
On a memory level, is there any difference in the oute?
(This is just a theoretical question, I am not trying to solve any problem in particular)
I have found this question that is related to this Difference between creating a class in javascript to create an object and creating an class and object in Java
Which states that there are no classes in JS.
Is this just syntactic sugar? 2 ways of doing exactly the same thing?
Let's say I want to create an array of Person
using a random data library.
I could do something like
import {generateRandom} from 'someLib'
let people = []
function getPerson() ({
name: generateRandom.string()
age: generateRandom.number()
})
for (let i = 0; i < 10; i++) {
people.push(getPerson())
}
But I could also do something like
import {generateRandom} from 'someLib'
class Person {
constructor() {
this.name = generateRandom.string(),
this.age = generateRandom.number()
}
}
let people = []
for (let i = 0; i < 10; i++) {
people.push(new Person())
}
On a memory level, is there any difference in the oute?
(This is just a theoretical question, I am not trying to solve any problem in particular)
I have found this question that is related to this Difference between creating a class in javascript to create an object and creating an class and object in Java
Which states that there are no classes in JS.
Is this just syntactic sugar? 2 ways of doing exactly the same thing?
Share Improve this question asked Dec 2, 2022 at 8:35 Michael VigatoMichael Vigato 3364 silver badges12 bronze badges 8- 3 This may be a theoretical question but it's useless without a concrete context. The code you have is not really representative. If you had methods on the instance and/or inherited properties, then a class will be more efficient, as you won't need to re-create each of these on each instance. But a plain object might work better in other cases. Even then, chances are that in many other cases there would be no meaningful difference. Moreover, the memory footprint may depend on the engine you run the code. Different context and optimisations might change that. – VLAZ Commented Dec 2, 2022 at 8:40
- 2 That's a different question than what's in the title. – VLAZ Commented Dec 2, 2022 at 8:47
-
3
Do you realize that in your first code block
getPerson()
isn't even shown with valid syntax (it results inSyntaxError
when run) and doesn't even attempt to return the object you created from the function. – jfriend00 Commented Dec 2, 2022 at 9:44 - 1 " I am wondering if the oute of these 2 pieces of code are exactly the same under the hood" That is implementation dependent, even if we can tell you whether that is true, today, for a given implementation, there's no guarantee it will stay that way. – Jared Smith Commented Dec 2, 2022 at 19:50
- 2 Why are you even asking for "the memory level"? The two codes are not even equivalent at the javascript level, creating different objects that inherit different properties from different prototypes. – Bergi Commented Dec 2, 2022 at 19:53
2 Answers
Reset to default 9If you want to examine the memory yourself, you can put this code in the console:
class Test{};
const test = new Test();
class Class {};
test.Class = Class;
test.classObj = new Class();
function func() {return {};};
test.func = func;
test.funcObj = func();
Take a heap snapshot with google chrome dev tools, sort by constructor and find the Test
class.
You can then examine the memory of these functions and objects. Here's a screenshot of what I got:
You can see that the object instantiated by the class constructor is slightly larger than the one instantiated by the function. Expanding the prototype, you can see they both use the Object
constructor, but the classObj
has the additional Class
constructor in its prototype chain.
You can also see that the class constructor appears to retain more memory than regular functions, retained size meaning memory that will be cleaned up by garbage collection if the function is no longer in use.
Seems to be an extra 172 bytes for the class constructor, and 24 bytes per object for an empty object.
Following VLAZ's ment, here's the results with 10 methods added, and 10 instances.
class Test{};
const test = new Test();
class Class {
method0(){};
method1(){};
method2(){};
method3(){};
method4(){};
method5(){};
method6(){};
method7(){};
method8(){};
method9(){};
};
test.Class = Class;
for (let i=0; i < 10; i++){
test["classObj" + i] = new Class();
}
function func0(){};
function func1(){};
function func2(){};
function func3(){};
function func4(){};
function func5(){};
function func6(){};
function func7(){};
function func8(){};
function func9(){};
function constructorFunc() {
return {
method0: func0,
method1: func1,
method2: func2,
method3: func3,
method4: func4,
method5: func5,
method6: func6,
method7: func7,
method8: func8,
method9: func9,
};
};
test.constructorFunc = constructorFunc;
for (let i=0; i < 10; i++){
test["funcObj" + i] = constructorFunc();
}
The shallow size of the class objects are now much smaller. This seems to be due to the fact that they can just store a reference to the class prototype rather than reference all of their methods directly.
At first glance, the retained size of Class
seems to be smaller than constructorFunc
, but expanding Class
you can see a property named prototype
which is an object retaining an extra 1.38 KB. Adding that to the 520 B of the class itself pushes it above the retained memory of constructorFunc
. But the memory saved by creating instances of the class instead of an object will outweigh that pretty quick.
So seems like classes are the way to go.
Your first getPerson()
is invalid syntax and the function does not even attempt to return anything (if it was valid syntax). So, people.push(getPerson())
would generate an array of undefined
(if the syntaxError was fixed) which will be entirely different than your second code block which generates an array of objects.
If, what you meant to ask about was something like this:
let people = []
function getPerson() {
return {
name: generateRandom.string()
age: generateRandom.number()
}
}
for (let i = 0; i < 10; i++) {
people.push(getPerson())
}
Then, this and your class will each create an array of objects and those objects will each have your two properties on them. The Class will contain some additional setup on the prototype that allows for subclassing, but if you're just asking about using the object with two properties, then these two would fundamentally do the same thing.
On a memory level, is there any difference in the oute?
Without methods, your two properties will occupy the same amount of memory. The two properties are assigned directly to the object so those two properties use the same memory.
The class will actually set up a few other things on the object like a .constructor
property and the object will get its own separate prototype. The prototype is shared among all instances. So, there could be slightly more memory usage for the class instance, but it's unlikely this makes a material difference.
If you defined methods directly on the object in the first implementation and methods in the class in the second implementation, then the class would definitely be more efficient because there would be one copy of the methods on the prototype vs. many separate copies of the methods on each instance of the object. But, you didn't show that in your question.
Which states that there are no classes in JS. Is this just syntactic sugar? 2 ways of doing exactly the same thing?
Classes are syntactic sugar, but they make it easy to define things in an efficient way without having to do a bunch of manual things. And, because the language sets things up for you, then everyone using a class definition creates code that works the same way.
You can manually build the same object that instantiating an instance of a class does, but it's a lot more code to do write all the bookkeeping that a class does for you. Your simple object with just two instance properties doesn't show any of that or need any of that, but when you start having methods and sub-classing things and overriding base methods and then calling base methods in your derived implementation, the class
definition takes care of a some bookkeeping for you and simply lets you write, good extensible code faster and with everyone doing it the same way. Again, your simple object with just two properties does not show or need what a class
does, but other uses of objects do.
For example, the class
definition and new Person()
creates an object that automatically sets yourObject.constructor
to be the constructor that created the object. This allows other code to know what type of object it is or allows other code to abstractly create new instances of the same object. Methods are put on the prototype of the object and made non-enumerable. Constructors can call super(...)
to execute the base class constructor (whatever it happens to be). Without the class definition, you have to do that very manually by calling the exact right function in the base class.
本文标签:
版权声明:本文标题:javascript - On a memory level, is there a difference between creating an object and creating a class instance in JS? - Stack Ov 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744264763a2597895.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论