淺析 String 類型的 slice()、substr()、substring()方法

今天咱們來聊聊 String 類型提供的三個方便而又非常相似的截取方法:
1. slice()
2. substr()
3. substring()

它們的相似體現在兩個方面:

  1. 功能:都是截取字符串,並且都返回一個新的字符串

  2. 參數:都支持接受兩個參數,第一個參數都是代表截取的開始位置。第二個參數除了 substr() ,其他兩個 slice()substring() 都是代表截取的結束位置

  3. 都只接收一個參數的情況下,都是從起始位置一致截取到末尾

let str = 'abcdefg';
let sli = str.slice(2);
let sub = str.substr(2);
let subs = str.substring(2);

上面這段代碼體現的就是上面提到的第三個共同點:

都只接收一個參數的情況下,都是從起始位置一致截取到末尾。

即他們的輸出結果都是:cdefg

哎喲,這麼一看,還真挺像的!那他們的不同之處呢?

上代碼 ——-

// 還是上面的例子,咋們加上第二個參數

let str = 'abcdefg';
let sli = str.slice(2, 5);  // 'cde'
let sub = str.substr(2, 5);  // 'cdefg'
let subs = str.substring(2, 5);  // 'cde'

通過上面這段代碼,我們可以很容易發現 substr 的叛逆個性:第二個參數代表的並不是截取的結束位置。而是截取字段的長度。

那如果截取的結束位置超過字符串末位的索引,會發生什麼情況呢,會報錯嗎?

好奇心驅使我修改了一下代碼:

let str = 'abcdefg';
let sli = str.slice(2, 10);  // 'cdefg'
let sub = str.substr(2, 10);  // 'cdefg'
let subs = str.substring(2, 10);  // 'cdefg'

這三個方法很強大,並沒有因爲我們的無理要求而報出錯誤,爲了驗證截取的長度是否溢出,逐個 console.log 了一下他們的 length 長度,都是 5 ,沒問題

如果起始位置大於字符串長度的情況:

let str = '12345';
let sli = str.slice(6, 8);  // ''
let sub = str.substr(6, 2);  // ''
let subs = str.substring(6, 8);  // ''

很顯然,當初始位置大於字符串長度時,截取的爲空字符串 ''

所以這三個方法,當截取到末尾時,便會停止截取,不會往後面加上空格

以上是其中兩種特殊的情況,還有一種情況就是,參數爲負數的情況:

這種情況下三個方法的表現各不相同,我們分開討論下

1. 先看看 slice() 的情況

let str = '12345';
let sli1 = str.slice(-3, 4);  // '34'
let sli1 = str.slice(3, -1);  // '4'
let sli1 = str.slice(-3, -1);  // '34'

可以看出 slice() 方法會將傳入的負數與字符串的長度相加,將其轉爲正數的情況,如 str.slice(-3, 4) 就相當於 str.slice(2, 4)

2. 之後是 substr() 的情況

let str = '12345';
let sli1 = str.substr(-3, 2);  // '34'
let sli1 = str.substr(3, -1);  // ''
let sli1 = str.substr(-3, -1);  // ''

substr() 第一個參數也是將傳入的負數與字符串長度相加,轉爲正數。重點是第二個參數,如果是負數則會默認截取的長度爲 0。所以最後兩條語句都返回了空字符串 ''

3. 最後是 substring() 的表現

let str = '12345';
let sli1 = str.substring(-3, 3);  // '123'
let sli1 = str.substring(3, -1);  // '123'
let sli1 = str.substring(-3, -1);  // ''

這段代碼中,我們發現了兩點:

(1)substring() 會把接收到的負數,全部轉爲 0 再進行截取。

(2)接收兩個參數時,該方法會先對比兩個參數的大小(如有負數會先處理再比較),把較小的一方當做截取的開始位置,較大一方當做截取的結束位置

尤其是第二點特徵,slice() 的話,不會對兩個參數進行對比,如果第一個參數大於第二個參數,會直接返回空字符串

總結

通過分析了他們在不同參數情況下的表現,最後把他們進行一個小小的總結:
相同點在文章開頭已經總結,接下來是區別:

  1. slice() 兩個參數分別代表着截取的開頭和結尾,而 substr() 的第二個參數則代表着截取的位數(即長度),substring() 先對兩個參數進行大小對比,再確定截取區域

  2. 三個方法如果截取到末尾,便會停止截取,無論參數約定的結束位置、或約定的長度有多大。

  3. 當參數爲負數的情況:slice() 會把負數與字符串的長度相加,得到的正數再執行代碼。substr() 第一個參數也是把負數與字符串的長度相加得到正數,第二個參數則會把負數轉爲 0substring() 則會把所有負數參數轉爲 0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章