面试题答案
一键面试基本数据类型和引用数据类型的存储方式
- 基本数据类型:
- 存储位置:基本数据类型(
undefined
、null
、boolean
、number
、string
、symbol
)在内存中直接存储在栈(stack)中。栈是一种后进先出的数据结构。例如,声明一个变量let num = 5;
,num
变量和它的值5
都存储在栈中。 - 特点:这种存储方式使得基本数据类型的访问速度较快,因为直接在栈中就能获取到值。而且基本数据类型是按值访问的,每个基本数据类型的值都是独立的,修改一个变量不会影响其他变量。例如:
let a = 10; let b = a; b = 20; console.log(a); // 10
- 存储位置:基本数据类型(
- 引用数据类型:
- 存储位置:引用数据类型(如
Object
、Array
、Function
等)在内存中分为两部分存储。对象的实际数据存储在堆(heap)中,而在栈中只存储一个指向堆中实际数据的引用地址。例如,当声明let obj = {name: 'John'};
时,obj
变量存储在栈中,它的值是一个指向堆中{name: 'John'}
对象的内存地址。 - 特点:由于引用数据类型是按引用访问的,当多个变量引用同一个对象时,对其中一个变量的修改会影响到其他变量。例如:
let obj1 = {value: 10}; let obj2 = obj1; obj2.value = 20; console.log(obj1.value); // 20
- 存储位置:引用数据类型(如
对变量声明、赋值和传递的影响
- 变量声明:
- 基本数据类型:声明时直接在栈中分配空间存储值。例如
let num = 10;
,就在栈中为num
变量分配存储10
的空间。 - 引用数据类型:声明时在栈中分配空间存储引用地址,实际对象在堆中创建。例如
let arr = [];
,在栈中为arr
变量分配空间存储指向堆中创建的空数组的地址。
- 基本数据类型:声明时直接在栈中分配空间存储值。例如
- 变量赋值:
- 基本数据类型:赋值是值的拷贝。如
let a = 5; let b = a;
,b
会得到a
值5
的一个副本,a
和b
相互独立。 - 引用数据类型:赋值是引用的拷贝。如
let obj1 = {prop: 1}; let obj2 = obj1;
,obj2
和obj1
指向堆中的同一个对象,对obj2
的修改会反映在obj1
上。
- 基本数据类型:赋值是值的拷贝。如
- 变量传递(以函数参数为例):
- 基本数据类型:传递的是值的副本。例如:
function changeValue(num) { num = num + 1; return num; } let num = 5; let newNum = changeValue(num); console.log(num); // 5
- 引用数据类型:当传递一个对象作为函数参数时,传递的是对象的引用地址。函数内部对对象的修改会影响到原始对象。例如:
在JavaScript引擎内部,当传递对象作为函数参数时,实际上是将栈中存储的对象引用地址传递给函数。函数内部通过这个引用地址来操作堆中的实际对象。function changeObject(obj) { obj.prop = obj.prop + 1; return obj; } let obj = {prop: 1}; let newObj = changeObject(obj); console.log(obj.prop); // 2
不同JavaScript引擎的差异和优化策略
- V8引擎:
- 差异:V8引擎采用了基于即时编译(JIT)的策略。它将JavaScript代码首先编译成字节码,然后在运行时根据实际执行情况进一步优化编译为机器码。在处理数据类型时,V8使用了内联缓存(IC)技术。例如,对于对象属性的访问,V8会缓存属性的偏移量,这样在后续访问时可以直接通过偏移量快速获取属性值,提高访问效率。
- 优化策略:V8引擎还使用了分代垃圾回收机制。它将堆内存分为新生代和老生代,新生代主要存放存活时间较短的对象,老生代存放存活时间较长的对象。针对新生代和老生代采用不同的垃圾回收算法,提高垃圾回收效率,减少内存碎片化。
- SpiderMonkey引擎:
- 差异:SpiderMonkey引擎在历史上更侧重于解释执行,不过后来也引入了即时编译技术。它的对象模型和V8略有不同,在处理对象属性的动态添加和删除时,SpiderMonkey的性能表现可能与V8有所差异。例如,SpiderMonkey可能在对象动态变化较大的场景下有不同的优化方式。
- 优化策略:SpiderMonkey使用了一种称为“Shapes”的技术来优化对象属性访问。Shapes记录了对象属性的布局信息,当对象属性布局稳定时,可以通过Shapes快速访问属性。同时,SpiderMonkey也在不断改进垃圾回收算法,以提高内存管理效率。