关于javascript:js函数传递对象参数

5次阅读

共计 1551 个字符,预计需要花费 4 分钟才能阅读完成。

一、在 javascript 中数据类型能够分为两类:

  • 原始数据类型值 primitive type,如 Undefined,Null,Boolean,Number,String。
  • 援用类型值,也就是对象类型 Object type, 如 Object,Array,Function,Date 等。

二、申明变量时不同的内存调配

  • 原始值:存储在栈(stack)中的简略数据段,也就是说,它们的值间接存储在 变量拜访的地位 。这是因为这些原始类型占据的空间是固定的,所以可将他们存储在较小的内存区域 –“”中。这样存储 便于迅速查寻变量的值
  • 援用值:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存地址。这是因为:援用值的大小会扭转,所以不能把它放在栈中,否则会升高变量查寻的速度。相同,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。

三、不同的内存分配机制也带来了不同的拜访机制

在 javascript 中是不容许间接拜访保留在“堆”内存中的对象的,所以在拜访一个对象时,首先失去的是这个对象在堆内存中的地址,而后再依照这个地址去取得这个对象中的值,这就是传说中的 按援用拜访。而原始类型的值则是能够间接拜访到的。

1、复制变量时的不同

  • 原始值:在将一个保留着原始值的变量复制给另一个变量时,会将原始值的正本赋值给新变量,尔后这两个变量是齐全独立的,他们只是领有雷同的 value 而已。
  • 援用值:在将一个保留着对象内存地址的变量复制给另一个变量时,会把这个内存地址赋值给新变量,也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个作出的扭转都会反映在另一个身上。(这里要了解的一点就是,复制对象时并不会在堆内存中新生成一个截然不同的对象,只是多了一个保留指向这个对象指针的变量罢了)

2. 参数传递的不同

首先咱们应该明确一点:ECMAScript 中所有函数的参数都 是按值来传递 的。然而为什么波及到原始类型与援用类型的值时依然有区别呢,还不就是因为内存调配时的差异。(这个复制变量时遵循的机制齐全一样)

  • 原始值:只是把变量里的值传递给参数,之后参数和这个变量互不影响。
  • 援用值:对象变量它外面的值是这个对象在堆内存中的内存地址,这一点你要时刻铭记在心!因而它传递的值也就是这个内存地址,这也就是为什么函数外部对这个参数的批改会体现在内部的起因了,因为它们都指向同一个对象呀。图示阐明:

所以,如果是按援用传递的话,是把第二格中的内容(也就是变量自身)整个传递进去(就不会有第四格的存在了)。但事实是变量把它外面的值传递(复制)给了参数,让这个参数也指向原对象。因而如果在函数外部给这个参数赋值另一个对象时,这个参数就会更改它的值为新对象的内存地址指向新的对象,但此时原来的变量依然指向原来的对象,这时候他们是互相独立的;但如果这个参数是扭转对象外部的属性的话,这个扭转会体现在内部,因为他们独特指向的这个对象被批改了呀!来看上面这个例子吧:(传说中的 call by sharing)

var obj1 = {value:'花点工夫 1'}; 
var obj2 = {value:'花点工夫 2'}; 
function changeStuff(obj){ 
    obj.value = '花点工夫 3'; 
    obj = obj2; 
    return obj.value; 
} 
var foo = changeStuff(obj1); 
console.log(foo);// '花点工夫 2' 参数 obj 指向了新的对象 obj2 
console.log(obj1.value);//'花点工夫 3', 形参 obj 和对象 obj1 指向了独特的内存地址,obj 扭转后,堆(heap)内存中的对象扭转,因而 obj1 的值也产生了扭转。
正文完
 0