JavaScript中容易被誤解的兩個(gè)地方
1.?????? js 中的變量作用域 (Variable Scope)
和 java,c++ 中不同的地方是, js 中沒(méi)有塊作用域 (Block Scope) 。變量的作用域?qū)穆暶饕恢背掷m(xù)到 function 的結(jié)尾。看個(gè)例子就會(huì)明白了。
?? function testScope()
?? {
????? var a = "a" ;??
?
???? ? function g() { alert (a); }
????? g();?? // 這里輸出結(jié)果為 a ,因?yàn)?/span> a 的作用域?qū)⒊掷m(xù)到 function? testScope 的結(jié)尾
???????????????
?
???? for ( var i=0; i<2; i++)
???? {
?????? var a = "a is changed" ;? // 這里的變量 a 將覆蓋開始聲明的變量 a
????? ? var b = "b" ;??? //b 的作用域從聲明一直到 function 的結(jié)尾 ?????????
?
?????}
?
??? alert (a);??? // 輸出結(jié)果為 ? a is changed , js 首先查找到的 a 是在循環(huán)中定義的那個(gè)
??? alert (b);??? // 輸出為 b?? 在 java 中 , 此時(shí)將訪問(wèn)不到變量 b,b 已經(jīng)出了作用域 , 但是在 js 中是可以的 .
?
?
?? }
?
?
2. js 中的垃圾回收( garbage collection )
? ? ?js 也是一門采用垃圾回收機(jī)制的語(yǔ)言,和 java 一樣。 js 的解釋器負(fù)責(zé)分配和回收內(nèi)存。
? 程序員無(wú)需像 C ++中那樣手動(dòng)用 delete 釋放內(nèi)存。
但是 js 也有 delete 關(guān)鍵字 ,它是用來(lái) 刪除對(duì)象的屬性,或者刪除數(shù)組中的指定元素。并不能刪除對(duì)象本身。用法如下:
delete objectName.property
delete objectName[index]
delete property
參數(shù)
property |
|
?
第三種用法delete property
只能在
with
語(yǔ)句中使用,用來(lái)刪除對(duì)象的屬性。
補(bǔ)充:在微軟的JScript中有CollectGarbage()函數(shù)可以用來(lái)回收內(nèi)存,官方文檔不推薦使用此方法,你的程序不應(yīng)該依賴此方法。IE在最小化的時(shí)候會(huì)進(jìn)行回收內(nèi)存。
??
JavaScript中的傳值與傳引用
1. 傳值 (by value)
變量的值被復(fù)制出一份 , 與原來(lái)的值將不相干 , 也就是說(shuō)即使新的值被修改 , 原來(lái)的值也不會(huì)改變 , 在 JavaScript 中基本類型都是傳值的 .
function testPassValue()
{
?? var m=1;
?? var n=2;
??
?? // 將 m,n 的值復(fù)制一份 , 傳遞到 passValue
?? passValue(m,n);
??
?? alert (m);? // 將是原有的值
}
?
function passValue(a,b)
{
? a = a+b; // 改變 a 的值 , 這里 a 只是原有值的一份 copy
? alert (a);??
}
輸出結(jié)果:
3
1 ?
2. 傳引用 (by reference).
引用本身復(fù)制一份傳給 function, 引用指向的對(duì)象并沒(méi)有被復(fù)制傳遞 (java 中也是如此 ), 在 function 中 , 如果改變了對(duì)象的屬性的值 , 由于和原來(lái)的引用指向的是同一個(gè)對(duì)象 , 因此在通過(guò)原來(lái)的引用訪問(wèn)到的將是修改過(guò)的值 ;
但是如果只是在 function 中將引用指向一個(gè)新的對(duì)象 , 將不會(huì)改變?cè)瓕?duì)象的值 , 改變的只是復(fù)制的這一份引用 .
function testPassValue()
{
? var date = new Date (2006,02,27);
? alert (date.getDate());? // 輸出為 27
?
? // 將 date 引用本身復(fù)制一份 , 傳遞到 passReference, 注意 date 所指向的對(duì)象并沒(méi)有被復(fù) 制
? passReference(date);
? alert (date.getDate());? // 輸出為 12
?
? // 同上
? changeReference(date);
? alert (date.getDate());? // 輸出還為 12
}
function passReference(da)
{
?// 由于 da 和原引用指向的是同一個(gè)對(duì)象 , 在 function 外 , 通過(guò)原有的引用訪問(wèn)到的將是對(duì)象的 日期屬性值 , 將是修改之后的值 .
?? da.setDate(12);?
}
function changeReference(da)
{
?? // 此時(shí) da 引用實(shí)際上是原引用的一份 copy, 將引用本身重新賦值 , 將不會(huì)影響原引用
?? da= new Date (2007,05,11);?
// 將 da 引用指向一個(gè)新的對(duì)象 , 此時(shí)原引用指向的還是原來(lái)的對(duì)象
?? alert (da.getDate());???? // 輸出為 11
??
}
?
3 特殊的 String??
? 在 JavaScript 中 ,String 也傳引用的 . js 中只有 charAt 方法 , 而沒(méi)有對(duì)應(yīng)的修改方法 , 和 java 中的 String 相同 , 都具有不變性 .
var s1 = "hello" ;
?
var s2 = "hell" + "o" ;
?
if (s1 == s2)???
alert ( "s1 = s2" ) ;??????? ?// 這句會(huì)不會(huì)執(zhí)行 ? java 用的熟的人可能會(huì)認(rèn)為不會(huì)執(zhí)行 , 因 為 java 中的 == 比較的是同一性 . 事實(shí)上在 js 中對(duì) String== 比較的是值是否相等 , 所以這句 話會(huì)執(zhí)行 . 但是對(duì)其他的 Object == 比較和 java 中一樣是同一性 .
?