先看一道JS的笔试题:
var setObj=function (o) { o.name="小明"; o={}; o.name="北京市"; } var p={名称:“细细,年龄:24}; setObj (p); console.log (p);
答案是{名称:小明,age24};
在JavaScript中函数参数默认为引用类型。
<强>一。函数传递值类型:强>
代码实例如下:
函数addNum (num) { num +=10; 返回num; } var num=10; var=结果addNum (num); console.log (num);console.log(结果);
以上代码的弹出值分别为:10年和20年,下面进行一下分析:
声明变量num并复制为10,这个是矿工工会是一个值类型,当为函数传递参数的时候,是将此值复制一份传递给函数,所以在函数执行之后,num本身的值并没有被改变,函数中被改变的值仅仅是一个副本而已。
<强>二。函数传递引用类型:强>
函数setName (obj) { obj.name="青岛新锐”; } var web=新对象(); web.name="蚂蚁部落”; setName (web); console.log (web.name);
以上代码的弹出值是:“青岛新锐”、下面进行一下分析:
声明一个对象网络,它是一个引用类型,当为函数传递参数的时候,是传递的web对象的引用,也就是此对象的内存地址,所以在函数中修改属性的对象就是函数外面创建的对象本身。
<强>三。加深理解:强>
函数setName (obj) { obj.name="青岛新锐”; obj=新对象(); obj.name="蚂蚁部落”; } var web=新对象(); setName (web); console.log (web.name);
以上代码的弹出值是:青岛新锐,很多人可能会以为将会弹出“蚂蚁部落”,下面进行一下简单的分析:
在函数外面创建一个对象,并将对象的引用赋值给变量网络,网络中存储的是对象在内存中的存储地址,当为函数传递参数的,就是传递的在函数外面创建的对象的地址。在函数中,为外面创建的对象创建一个自定义属性名称并赋值为“青岛新锐”,然后又创建一个新的对象,并将新对象的地址赋值给obj,这个时候obj指向的并不是函数外面创建的对象,所以外面对象的名字属性不会被改变。
这样写对于其他语言的程序员来说是很难接受的,我们在实际的开发中避免这样的写法,因为这样会造成全局作用域污染。最近在读《javascript高级程序设计》时碰到了js传递方式的问题,花费了些时间,不过总算明白了。
<强>数据类型强>
在javascript中数据类型可以分为两类:
-
<李>基本类型值原始类型,比如未定义,Null,布尔值、数字、字符串。李>
<李>引用类型值,也就是对象类型对象类型,比如对象,数组,函数,日期等。李>
<强>变量的复制强>
众所周知,js中变量的基本类型和引用类型保存方式是不同的,这也就导致变量复制时也就不同了。如果从一个变量向另一个变量复制基本类型的值时,会将前者的值克隆一个,然后将克隆的值赋值到后者,因此这两个值是完全独立的,只是他们的价值相同而已。
var num1=10; var num2=num1; console.log (num2);//10
上面的num1中被保存的值为10,当把num1的值赋值给num2时,num2的值也为10。但是这两个10是完全独立的,num2中10只的是被克隆出来的,相当于我写了一个词文档,把它放到了num1的文件夹中,然后我再复制这个词文档,就叫词副本吧,然后把这个副本放到num2的文件夹下,这两个词文档是完全一样的,修改任何一个都不会影响两一个。
num2 +=1; console.log (num1);//10 console.log (num2);//11
从上面可以看出修改num2的值,num1的值未发生变化。再来看下引用类型的复制。当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到为新变量分配的空间中。
var其中obj1={ 名称:“111” }; var methoda=其中obj1; console.log (obj2.name);//111 obj2.name=" 222 "; console.log (obj1.name);//222