在内存层面上,在JS中创建对象和创建类实例有区别吗?

Mic*_*ato 2 javascript arrays object node.js

假设我想Person使用随机数据库创建一个数组。

我可以做类似的事情

import {generateRandom} from 'someLib'

let people = []

function getPerson() ({
  name: generateRandom.string()
  age: generateRandom.number()
})

for (let i = 0; i < 10; i++) {
  people.push(getPerson())
}
Run Code Online (Sandbox Code Playgroud)

但我也可以做类似的事情

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()) 
}

Run Code Online (Sandbox Code Playgroud)

在记忆层面上,结果有什么不同吗?


(这只是一个理论问题,我并不是想特别解决任何问题)

我发现这个问题与此Difference betweencreate a class in javascript to create an object 和create an class and object in Java有关

这表明 JS 中没有类。

这只是语法糖吗?两种方法做完全相同的事情?

Chr*_*ton 6

如果你想自己检查内存,可以将这段代码放在控制台中:

class Test{};

const test = new Test();

class Class {};
test.Class = Class;
test.classObj = new Class();

function func() {return {};};
test.func = func;
test.funcObj = func();
Run Code Online (Sandbox Code Playgroud)

使用 google chrome 开发工具拍摄堆快照,按构造函数排序并找到该类Test

然后您可以检查这些函数和对象的内存。这是我得到的屏幕截图:

第一个结果

可以看到类构造函数实例化的对象比函数实例化的对象稍大。展开原型,您可以看到它们都使用了Object构造函数,但其​​原型链中classObj有额外的构造函数。Class

您还可以看到,类构造函数似乎比常规函数保留更多的内存,保留的大小意味着如果不再使用该函数,将通过垃圾回收清理内存。

对于类构造函数来说似乎需要额外的 172 个字节,对于空对象来说每个对象需要额外的 24 个字节。


根据 VLAZ 的评论,以下是添加了 10 个方法和 10 个实例的结果。

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();
}
Run Code Online (Sandbox Code Playgroud)

所有对象

扩展类

类对象的浅层大小现在小得多。这似乎是因为它们只能存储对类原型的引用,而不是直接引用它们的所有方法。

乍一看, 的保留大小Class似乎比 更小constructorFunc,但是展开后Class可以看到名为which 的属性,prototype它是一个保留了额外1.38 KB 的对象。将其添加到类本身的 520 B 中,将其推到 的保留内存之上constructorFunc。但是通过创建类实例而不是对象所节省的内存很快就会超过这个值。

所以看来上课是一条出路。