天天看點

【JavaScript基礎系列】決定你的人生能走多遠的,是基礎。

前言

   javaScript門檻非常低,一點文法,一個dom,一個bom就可以使用它開發大部分js應用,再加上現在層出不窮的架構極大的簡化抽象了javaScript的使用方式,但是我們始終不能忘記的一點是,決定上層建築的,是經濟基礎。 決定你的javaScript能走多遠的,是基礎。是以我決定在我的部落格開一個關于javaScript基礎系列。詳細得,解讀其中的基礎,再次刨開它的心髒細細研究。與大家共勉。

第一篇 字元串一

   我們從字元串開始介紹。

  字元串(String)  基礎概念:一串有意義的字元集合叫做字元串,在js中使用單引号‘string’ 或者雙引号 "string"表示字元串。它是js五個基本類型之一,姑且可以認為它是js基本類型中特性最多的,技巧最多的基本類型。其他的如Number、boolean、null、undefined,其使用方式,引用方法,概念都沒有字元串來得多。

  了解js中的字元串的使用原理

  一、字元串的表達形式。

    ① 通過字面表達式定義的字元串。

     1 var str = "這是一串字元串"; 

    聲明了一個變量str ,給這個變量指定值字元串 “”; 

    ②通過js内置的String構造函數,

1 /*****************************
2                 通過構造函數定義的字元串,
3                 實際上可以叫做字元串對象,
4                 在chorme中傳回一個字元拆分的對象
5 */
6                 var str = new String("hello world"); 
7                 console.log(str);      

  二、字元串與字元串對象(為什麼普通字元串可以調用構造函數的方法?)。

  通過字面表達式定義的字元串與通過js内置的String構造函數生成的字元串,它們在使用的時候,行為似乎是一緻的,但是,在更正确的表達中,它們是不同的,通過字面表達式我們直接給變量賦予了一個字元串值,而通過構造函數,我們得到的是一個String對象。

  下圖是内置的String構造函數在chorme中傳回一個字元拆分的對象:

  

【JavaScript基礎系列】決定你的人生能走多遠的,是基礎。

  而字面量方式則是:

【JavaScript基礎系列】決定你的人生能走多遠的,是基礎。

  通過對兩個方式的typeof對比,我們可以看到:

/*****************************
                通過構造函數定義的字元串,
                實際上可以叫做字元串對象,
                在chorme中傳回一個字元拆分的對象
            */
                var str = new String("hello world"); 
                console.log(str);  //上圖1

            /*****************************
                通過typeof檢查的字元串對象,傳回了object
            */
                var _type = typeof str;
                console.log(_type)  //object

            /*****************************
                不使用構造函數,直接指派呢?
                它就是一個基本值,
                typeOf傳回string
            */
                var str1 = "hello world";
                console.log(str1); //上圖2

                var _type1 = typeof str1;
                console.log(_type1)  //string      

它們是否相等?答案是不相等,

console.log(str === str1); //false      

那麼我可以這麼簡單的了解:new操作符隻會傳回對象,new String()永遠都是一個對象,而對象是不會和字元串相等的。

有一點經驗的同學應該可以看出,這裡如果使用==的話,str==str1,傳回的是true。這是因為js中的類型轉換機制決定的,它隐式的調用了字元串對象的valueOf方法。我們可以做一個小實驗:

/***************************
                如果我重寫str的valueOf方法将它指向一個新的值
            */
            console.log("before ",str == str1);//true
            str.__proto__.valueOf = function(){
                return "javaScript!";
            }
            console.log("after ",str == str1);//false
       console.log(str+str1) //javaScript!hello world
      

我更改了str的原形對象中的valueOf方法,使它總是傳回一個新字元值 "javaScript!",最後再和str1用==比對的時候,傳回了false。

目前為止可以得出結論是,字元串和字元串對象不相等,甚至不是同一個概念,一個是基本類型值,一個是構造函數生成的字元對象,但在js機制中,比較時隐式的使用了valueOf方法,調用拼接時也隐式調用了valueOf方法。

js以這種方式給字元串“繼承”了一些方法,能看到的做法是,js在使用字面表達式定義的字元串調用方法時,悄悄的給它包了一層字元串對象的殼。

通過調用__proto__屬性就可以看出      
//通過調用__proto__屬性就可以看出
                
                console.log(str1.__proto__ === str.__proto__); //true 他們繼承的對象是相等的      

字元串與字元串對象的使用方式一緻,typeof得到的值不同,在使用字面表達式定義的字元串調用方法時,js會隐式調用new String(),這就是為什麼基礎類型能夠調用對象方法的原因。

通過這個了解方式,我們就不難了解為什麼一個數字、一個字元串能調用内置方法了。

 三、字元串下标

  字元串是有下标的。由于上面介紹的字元串與字元串對象的關系,任意字元串都可以通過下标通路到對應的位置的單個字元。下圖在chorme中列印的一個字元串對象:

【JavaScript基礎系列】決定你的人生能走多遠的,是基礎。

  可以看到一共11個字元從0到10,需要注意的是它并不是數組。而是一個屬性名為0-10的對象。

/*****************************
                 可以通過下标通路字元串字元
                 這裡字元串對象和字元串同樣能使用下标通路,
                 這是因為javascript編譯時,會在适當的時候将字元串包裝成字元串對象,
                 這樣一般的字元串就也可以調用String構造函數的方法了
            */
                console.log(str[0]); //h
                console.log(str1[0]); //h      

我們可以, 通過for循環列印每一個字元,也可以,通過數組的方法借用将字元串轉換成數組:

Array.prototype.slice.call(str)
//["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]      

但是需要注意的是,如果你直接修改str[11] = "!"的話,隻會在對象中新增了一個名為11的屬性,并不會修改到字元串本身的值。

str[11] = "!";
console.log(str.valueOf()) // hello world  修改失敗!      

為什麼js要這麼幹?将字元串存儲兩份,一份是一個一個的對象屬性字元集,另一份指向原始值,也就是上圖的 [[PrimitiveValue]].。

我覺得它們有一個先後關系,先生成一個一個的對象屬性,再由對象屬性的一個個字元拼接成 [[PrimitiveValue]];

單元總結

  真正的基礎是什麼?我覺得是它的内在原理,它的實作思路以及實作方式,是以文中并沒有給出更多的字元串操作方法,

  本章介紹了字元串調用方法的來曆,介紹了字元串下标的原理。下一章講什麼,待定,部落客是一邊回顧基礎,一邊了解,一邊寫部落格,當然也有很多不正确的地方,感謝大家包容,更感謝大家指正。

  最後

  ==============================================================================================

  一首詩

  我想寫一首詩,

  歌頌風,

  頌唱雨。

  隻是,

  我的桌子上沒有一支筆,

  詩沒有筆可能代表着,

  也許遠方不那麼遠,

  它就在筆上飛揚。

  ================================================================================================

  轉載請注明出處。 9月12日劃水的下午

========================================================

轉載請注明出處。

繼續閱讀