阿里巴巴面试题
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
原因如下:
js的引用指向的是值。js对值和引用的赋值/传递在语法上没有区别,完全根据值的类型来决定。
简单值(即标量基本类型)总是通过值复制的方式来赋值/传递,包括null、undefined、字符串、数字、布尔和ES6中的symbol。
复合值——对象(数组和对象)和函数,则总是通过引用复制的方式来赋值传递。引用指向的是值本身而非变量,所以一个引用无法更改另一个引用的指向。
/*
* 简单值值复制
* 1是一个标量基本类型,所以变量a持有该值的一个复本,b持有它的另一个复本。
* b更改时,a的值保持不变
*/
var a = 1;
var b = a;
b++;
a;//1
b;//2
/*
* 复合值引用复制
*c和d则分别指向同一个复合值[1,2,3]的两个不同引用
*注意,c和d仅仅是指向值[1,2,3],并非持有。
* 所以他们更改的是同一个值,随后他们都指向更改后的新值
*/
var c = [1,2,3];
var d = c;
d.push(4);
c;//[1,2,3,4]
d;//[1,2,3,4]
//当d指向一个新的复合值时,c的值不变
d=[4,5,6];
c;//[1,2,3,4]
/*函数参数理解
*
*/
function foo(x){
x.push(4)
x;//[1,2,3,4]
x = [4,5,6];
x.push(7);
}
var a = [1,2,3];
foo(a);
a;//[1,2,3,4];
//=> 在调用这个函数的时候可以这样理解;
function(var x= a){
//可以理解成x和a则分别指向同一个复合值[1,2,3]的两个不同引用
x.push(4)
x;//[1,2,3,4]
//当x指向新的复合值时[4,5,6],a的指向不会发生改变
x = [4,5,6];
x.push(7);
}
//所以a的值为[1,2,3,4],而不是[4,5,6,7]
我们无法自行决定使用值复制还是引用复制,一切由值的类型来决定 。
如果要将标量基本类型值传递到函数内并进行更改,就需要将该值封装到一个复合值(对象、数组)中,然后通过引用复制的方式传递。
function foo(wrapper){
wrapper.a = 2;
}
var obj = {
a:1
}
foo(obj);
obj.a;//2
《你不知道的javascript》中卷笔记以及加上自己的理解整理如上。