在 http://m.tkk7.com/magicdoom/archive/2006/02/27/32555.html中 有言:
“在JavaScript中,String也傳引用的.”
讓我們來看下面這個例子:
function setName(obj)
{
obj = "minchanghe";
}
var name = " hechangmin ";
setName(name);
alert(name); // hechangmin
發現輸出的 name并沒有發生變化,所以這地方還是值得我們進一步研究。
在上文
http://m.tkk7.com/JAVA-HE/archive/2010/03/18/315798.html 有講過,對于傳入的引用參數,如果重新賦值,將自動生成 拷貝,而不影響原來引用。
這時候我琢磨下面這個例子也許能通過引用參數來完成修改效果:
String.prototype.ok = "aaaaa";
function setName(obj)
{
obj.ok = "ccccccc";
}
var name = " hechangmin ";
alert(name.ok); // aaaaa
setName(name);
alert(name.ok); // aaaaa
不幸的是,上例還是失敗告終。這到底是什么呢?稍安勿躁,我的答案總會給出,即使不完全正確。
我們再來看下面這個例子:
var test = new String("minchanghe");
var name = "minchanghe";
alert(test == name); // true => 值相等
alert(test === name); // false => 類型不同
// 驗證下
alert(typeof test ); // object
alert(typeof name ); // string
我們很容易就得到了一個結論,通過new String 產生的字符串對象 和 以字符串常量產生的字符串對象他們是有區別的,即使他們有相同的值。
這時候也許你思考傳引用還有戲,因為我們還沒有試過 new String。 好,看下面的例子:
function setName(obj)
{
obj.ok = "ccccccc";
}
var name = new String("hechangmin");
String.prototype.ok = "aaaaa";
alert(name.ok); // aaaaa
setName(name);
alert(name.ok); // ccccccc
這個結果不錯吧。 的確實現了前后兩次輸出內容的變化。說明以 new String() ,你直接看成普通的object對象即可理解。 (前面用typeof驗證過這個也的確是 object )
本來文章寫到這里想結束了,結果發現前面留下的那個問題,并沒有解決。這時候我們不難找到資料來說明 new String 和 直接用字符串常量產生的字符串對象的區別在哪里?
在
《JavaScript 語言參考》中文版.chm 手冊上看到如下的說明:
String 對象可用字符串文字顯式創建。用這種方法創建的 String 對象(指以標準字符串形式)與用 new 運算符創建的 String 對象處理上不同。所有字符串文字共享公用的全局字符串對象。如果為字符串文字添加屬性,則它對所有標準字符串對象都是可用的:
var alpha, beta;
alpha = "這是一個字符串";
beta = "這也是一個字符串";
alpha.test = 10;
在前一示例中,這時為 beta 和所有將來的字符串定義 test。然而,在下面的例子中,被添加屬性的處理略有不同:
var gamma, delta;
gamma = new String("這是一個字符串");
delta = new String("這是也一個字符串");
gamma.test = 10;
在這種情況下,不為 delta 定義 test。每個用 new String 聲明的 String 對象有其自己的一組成員。這是對 String 對象和字符串文字的處理不同的唯一情況。
盡信書不如無書,我隨手試了下其中的代碼:
var alpha, beta;
alpha = "這是一個字符串";
beta = "這也是一個字符串";
alpha.test = 10;
alert(beta.test); //undefined
靠,這手冊也太不經不起驗證了吧。。。那上面那個問題怎么辦?
一個辦法:如果以字符串常量產生的字符串對象以傳值來看待。
想起曾經的一個bug,這里提一點:
1.toString 函數返回string
2.var x = String("a"); 生成string
3.new String() 創建object
有一次以json跟C++ GUI 通信過程 ,我居然 new String()了,這個bug很低級,但是卻讓我找得比較辛苦。
我又想起一篇介紹 javascript內存泄露的文章,如果有興趣可以訪問:
http://m.tkk7.com/JAVA-HE/archive/2009/10/27/299856.html
其中有講:
自動類型裝箱轉換:這種泄露存在于ie6 ie7中。這是極其匪夷所思的一個bug,看下面代碼
var s="lalalalala";alert(s.length);
這段代碼怎么了?看看吧,"lalalalala"已經泄露了。關鍵問題出在s.length上,我們知道js的類型中,string并非對象,但可以對它使用.運算符,為什么呢?因為js的默認類型轉換機制,允許js在遇到.運算符時自動將string轉換為object型中對應的String對象。而這個轉換成的臨時對象100%會泄露(汗一下)。
當然看到這里我有疑惑,前面的示例我有:alert(name.ok);
那是否就應該說這里有自動裝箱機制編程 object呢? 如果變成object后,那地方的傳引用實驗能成功才對啊?
哈哈,中計了,其實裝箱那地方產生的只是臨時對象。
posted on 2010-03-18 18:30
-274°C 閱讀(2801)
評論(0) 編輯 收藏 所屬分類:
web前端