当前位置: 首页 > 面试题库 >

物理内存中的JavaScript数组如何表示?

慕皓君
2023-03-14
问题内容

据我了解,我可以将混合数据存储在JavaScript数组中,也可以将数组中的任何元素更改为其他类型。解释器如何跟踪任何元素在物理内存中的位置。另外,如果将元素更改为更大的数据类型,那么如何防止下一个元素中的数据被覆盖。

我假设数组仅存储对实际对象的引用,并且将基元放置在数组中时将其包装在幕后。

假设是这种情况,如果我对原始变量有不同的句柄并更改存储在数组中的值是否保持同步?

我知道我可能已经回答了我自己的问题,但是我不确定,因此也找不到任何信息。


问题答案:

通常,数组分配固定长度的连续内存块。但是,在Javascript中,数组是具有特殊构造函数和访问器方法的Object类型。

意思是说:

var arr = new Array(100000);

不分配任何内存!实际上,它只是在数组中设置length属性的值。构造数组时,不需要声明大小,因为它们会自动增长。因此,您应该改用以下方法:

var arr = [];

Javascript中的数组是稀疏的,这意味着并非数组中的所有元素都可能包含数据。换句话说,只有实际包含数据的元素存在于数组中。这减少了阵列使用的内存量。这些值是通过键而不是偏移量定位的。它们只是一种便捷的方法,并不打算用于复杂的数值分析。

Javascript中的数组未输入类型,因此元素的值可以是对象,字符串,数字,布尔值,函数或数组。数组和对象之间的主要区别是length属性,该属性的值大于数组中最大的整数键。

例如:

您可以创建一个空数组,并在索引0和索引99处添加两个元素。长度为100,但数组中的元素数为2。

var arr = [];
arr[0] = 0;
arr[99] = {name: "John"};
console.log(arr.length); // prints 100
arr; // prints something like [0, undefined × 98, Object { name: "John"}]

要直接回答您的问题:

问:据我了解,我可以将混合数据存储在JavaScript数组中,也可以将数组中的任何元素更改为其他类型。解释器如何跟踪任何元素在物理内存中的位置?另外,如果将元素更改为更大的数据类型,如何防止下一个元素中的数据覆盖?

答:如果您已经阅读了上面的评论,那么您现在可能已经知道了。在Javascript中,数组是Hashtable
Object类型,因此解释器不需要跟踪物理内存,并且更改元素的值不会影响其他元素,因为它们不会存储在连续的内存块中。

-

问:我假设数组仅存储对实际对象的引用,而基元放置在数组中时会被包装在幕后。假设是这种情况,如果我对原始变量有不同的句柄并更改存储在数组中的值是否保持同步?

答:不,基元没有包装。更改分配给数组的基元不会更改数组中的值,因为它们是按值存储的。另一方面,对象是通过引用存储的,因此更改对象值将反映该数组中的更改。

您可以尝试以下示例:

var arr = [];
var obj = { name: "John" };
var isBool = true;

arr.push(obj);
arr[1] = isBool;

console.log(arr[0]); // print obj.name
console.log(arr[1]); // print true

obj.age = 40;        // add age to obj
isBool = false;      // change value for isBool

console.log(arr[0]); // value here will contain age
console.log(arr[1]); // value here will still be true

另外,请注意,当您通过以下两种方式初始化数组时,它具有不同的行为:

var arr = new Array(100);
console.log(arr.length);        // prints 100
console.log(arr);               // prints []

var arr2 = new Array(100, 200);
console.log(arr2.length);       // prints 2
console.log(arr2);              // prints [100, 200]

如果要使用Javascript数组作为连续的内存块,则应考虑使用TypedArray。TypedArray允许您将内存块分配为字节数组,并更有效地访问原始二进制数据。

您可以通过阅读[ECMA-262规范版本5.1)来了解有关Javascript复杂性的更多信息。



 类似资料:
  • 问题内容: 众所周知,在Java中,二维数组是多维一维数组。这意味着那些一维数组在内存中不连续。 相反,在C中,二维数组实际上是大小为 total_row * total_column的 一维数组。因为Go语言使用了C语言中的许多概念。所以我的问题是:Go语言中的二维数组的内存表示是否像C或Java中那样? 问题答案: 在Go中,通常将slice误认为是array,所以我对两者都作了回答。 数组

  • 物理内存管理 接下来将首先对实验的执行流程做个介绍,并进一步介绍如何探测物理内存的大小与布局,如何以页为单位来管理计算机系统中的物理内存,如何设计物理内存页的分配算法,最后比较详细地分析了在80386的段页式硬件机制下,ucore操作系统把段式内存管理的功能弱化,并实现以分页为主的页式内存管理的过程。

  • 物理内存管理 物理页 通常,我们在分配物理内存时并不是以字节为单位,而是以一物理页(Frame),即连续的 4 KB 字节为单位分配。我们希望用物理页号(Physical Page Number,PPN)来代表一物理页,实际上代表物理地址范围在 [PPN×4KB,(PPN+1)×4KB)[\text{PPN}\times 4\text{KB},(\text{PPN}+1)\times 4\text

  • 归功于 GRUB ,在启动后,内核可以知道可用物理内存的大小。 在实现操作系统时,前 8Mb 字节的物理内存将被内核保留使用,这些内存被用来存放: The kernel 内核 GDT, IDT et TSS Kernel Stack 内核栈 Some space reserved to hardware (video memory, ...) 保留硬件所需空间 Page directory and

  • 在与 GDT 相关的章节中,我们知道分段物理内存地址使用的是段选择和计算偏移(Linux在X86上的虚拟内存管理) 在本章中,我们将实现内存的分页功能,其原理是将分段的线性地址转换成物理地址(分页表存储了虚拟(线性)地址到物理地址间的映射)。 为什么我们需要分页管理内存? 内存分页将允许我们的内核: 为避免歧义,保留部分原文 use the hard-drive as a memory and n

  • 物理内存探测 物理内存的相关概念 我们知道,物理地址访问的通常是一片 DRAM,我们可以把它看成一个以字节为单位的大数组,通过物理地址找到对应的位置进行读写。但是,物理地址并不仅仅只能访问 DRAM,也可以用来访问其他的外设,因此你也可以认为 DRAM 也算是一种外设,物理地址则是一个对可以存储的介质的一种抽象。 而如果访问其他外设要使用不同的指令(如 x86 单独提供了 in 和 out 等指令