在 http://www.aygfsteel.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://www.aygfsteel.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://www.aygfsteel.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 閱讀(2807) 評論(0)  編輯  收藏 所屬分類: web前端

          常用鏈接

          留言簿(21)

          隨筆分類(265)

          隨筆檔案(242)

          相冊

          JAVA網站

          關注的Blog

          搜索

          •  

          積分與排名

          • 積分 - 916114
          • 排名 - 40

          最新評論

          主站蜘蛛池模板: 武夷山市| 麻阳| 顺昌县| 宣武区| 庆阳市| 台江县| 南宫市| 宝山区| 建水县| 平和县| 湟源县| 四平市| 溧阳市| 沂南县| 东莞市| 特克斯县| 汉川市| 泸溪县| 广德县| 安图县| 芷江| 浦北县| 五河县| 库尔勒市| 浦县| 金坛市| 隆子县| 章丘市| 蓝田县| 建瓯市| 宜宾市| 峨边| 平塘县| 荃湾区| 普陀区| 梅州市| 平武县| 延安市| 定结县| 伽师县| 辛集市|