| 
                         用汇编代码表示: 
- n -> 0x002233  
 - Heap: Stack:  
 - 002254 012222  
 - ... 012223 0x002233  
 - 002240 012224  
 - 002239 012225  
 - 002238  
 - 002237  
 - 002236  
 - 002235  
 - 002234  
 - 002233 { number: 90 }  
 - 002232  
 - 002231 { number: 30 }  
 - Code:  
 - ...  
 - 000233 main: // entry point  
 - 000234 push n // n 值为 002233 ,它指向堆中存放 {number: 90} 地址。 n 被推到堆栈的 0x12223 处.  
 - 000235 ; // 保存所有寄存器  
 - ...  
 - 000239 call sum ; // 跳转到内存中的`sum`函数  
 - 000240  
 - ...  
 - 000270 sum:  
 - 000271 ; // 创建对象 {number: 30} 内在地址主 0x002231  
 - 000271 mov 0x002231, (ebp+4) ; // 将内存地址为 0x002231 中 {number: 30} 移动到堆栈 (ebp+4)。(ebp+4)是地址 0x12223 ,即 n 所在地址也是对象 {number: 90} 在堆中的位置。这里,堆栈位置被值 0x002231 覆盖。现在,num1 指向另一个内存地址。 
 - 000272 ; // 清理堆栈  
 - ...  
 - 000275 ret ; // 回到调用者所在的位置(000240)  
 
  
我们在这里看到变量n保存了指向堆中其值的内存地址。 在sum 函数执行时,参数被推送到堆栈,由 sum 函数接收。 
sum 函数创建另一个对象 {number:30},它存储在另一个内存地址 002231 中,并将其放在堆栈的参数位置。 将前面堆栈上的参数位置的对象  {number:90} 的内存地址替换为新创建的对象 {number:30} 的内存地址。 
这使得 n 保持不变。因此,复制引用策略是正确的。变量 n 被推入堆栈,从而在 sum 执行时成为 n 的副本。 
此语句 num1 = {number:30} 在堆中创建了一个新对象,并将新对象的内存地址分配给参数 num1。 注意,在 num1 指向 n  之前,让我们进行测试以验证: 
- // example1.js  
 - let n = { number: 90 }  
 - function sum(num1) {  
 - log(num1 === n)  
 - num1 = { number: 30 }  
 - log(num1 === n)  
 - }  
 - sum(n)  
 - $ node example1  
 - true  
 - false  
 
  
是的,我们是对的。就像我们在汇编代码中看到的那样。最初,num1 引用与 n 相同的内存地址,因为n被推入堆栈。 
然后在创建对象之后,将 num1 重新分配到对象实例的内存地址。 
让我们进一步修改我们的例子1: 
- function sum(num1) {  
 - num1.number = 30  
 - }  
 - let n = { number: 90 }  
 - sum(n)  
 - // n 成为了 { number: 30 }  
 
  
这将具有与前一个几乎相同的内存模型和汇编语言。这里只有几件事不太一样。在 sum 函数实现中,没有新的对象创建,该参数受到直接影响。 
- ...  
 - 000270 sum:  
 - 000271 mov (ebp+4), eax ; // 将参数值复制到 eax 寄存器。eax 现在为 0x002233  
 - 000271 mov 30, [eax]; // 将 30 移动到 eax 指向的地址  
 
  
num1 是(ebp+4),包含 n 的地址。值被复制到 eax 中,30 被复制到 eax 指向的内存中。任何寄存器上的花括号 [] 都告诉 CPU  不要使用寄存器中找到的值,而是获取与其值对应的内存地址号的值。因此,检索 0x002233 的 {number: 90} 值。 
看看这样的答案: 
原始数据类型按值传递,对象通过引用的副本传递。                         (编辑:91站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |