js陣列及物件的賦值和引用
簡要歸納:
1、普通的賦值是複製棧區內容。
2、基本型別的資料在棧區存放資料自身,var a=b; //a與b無關。
引用型別資料在棧區存放資料地址。 var a=b; //a,b聯動
3、基本資料型別包括:undefined,boolean,number,string,null
引用型別:物件、陣列、函式。
舉例說明:
引數傳遞:
js的函式引數傳遞為值傳遞,個人理解傳參是複製了份棧區內容給函式。只不過基本型別棧區存放資料,所以傳入值與原值等值但不相關;引用型別棧區存放資料地址,傳入值為一個地址,所以傳入值和原值都可以通過地址訪問或修改堆區資料。
1、當傳入的是 基本型別的引數時:就是複製了份內容給i而已,i與age之間沒有關係。
function setAge(i)
{ alert(i); //24 i = 18; alert(i); //18,i的改變不會影響外面的age }; var age = 24; setAge(age); alert(age);//242、當傳入的引數為引用型別時:複製了地址給函式,函式可通過地址修改堆區資料。
function setName(obj)
{ obj.name = 'haha'; }; var obj2 = new Object(); setName(obj2);- var a = [1, 2, 3];
- var b = [5, 6];
- var c=100;
- function change(a,b,c) {
- c=99;
- a[0] = 4;
- var c = a;
- a = b;
- b = c;
- }
- change(a,b,c);
- alert(c); //"100";
-
alert(a); //"4,2,3"
- alert(b); //"5,6"
另一個例子:
var a = [1,2,3];
var b = a;
a = [4,5,6];
alert(b); //[1,2,3]
看了前面的內容,此處很容易認為第三步時修改了地址指向的資料,從1,2,3修改為4,5,6, 所以alert(b); //[4,5,6]但要搞清建立物件和其他的區別。第三步意味建立了一個[4,5,6]的物件,並將其地址賦給a. 所以a不再指向[1,2,3].
同理,若想要b有a的值,但不想聯動。可以有以下方法:
方法一:用jq的$.extend方法
[html] view plain copy print?- <scripttype="text/javascript">
- var a=[1];
- var b;
- b= $.extend(true,{},a)
- b[0]++;
- alert(b[0]);
- </script>
方法二:用陣列的concat方法 [html] view plain copy print?
- <scripttype="text/javascript">
- var a=[1];
- var b=a.concat();
- b[0]++;
- alert(a[0]);
- </script>
方法三:for迴圈陣列,挨個賦值。
var a=[1,2,3];
var b=[];
for(var i=0; i<a.length; i++){
b[i]=a[i];
}
方法四:陣列的slice()方法。
arrayObject.slice(start,end)返回一個新陣列,包含從start到end(不包含此元素)的arrayObject中元素。該方法不修改原陣列,而是返回一個新陣列。
var arr =["a","b","c","d","e"]; var arr1=arr.slice(2,4); console.log(arr1); //"c,d" var arr2=arr.slice(0); console.log(arr2); //"a,b,c,d,e" arr2[2]="wang" console.log(arr); //"a,b,c,d,e" 與原陣列不聯動 console.log(arr2); //"a,b,wang,d,e"
阿里2014年的筆試題:
var a = 1;
var obj = { b: 2 }; var fn = function () {}; fn.c = 3; function test(x, y, z) { x = 4; y.b = 5; z.c = 6; return z; } test(a, obj, fn); alert(a + obj.b + fn.c);答案:12
首先test傳遞進去的實參中,a是基本型別(,複製了一份值),obj是object(指向地址,你動我也動),fn也當然不是基本型別啦。在執行test的時候,x被賦值為4(跟a沒關係,各玩各的,a仍然為1),y的b被賦值為5,那obj的b也變為5,z的c變為6,那fn的c當然也會是6. 所以alert的結果應該是1+5+6 =12. (其實test不返回z也一樣,z仍然改變的)。