今天咱們來聊聊 String 類型提供的三個方便而又非常相似的截取方法:
1. slice()
2. substr()
3. substring()
它們的相似體現在兩個方面:
功能:都是截取字符串,並且都返回一個新的字符串
參數:都支持接受兩個參數,第一個參數都是代表截取的開始位置。第二個參數除了
substr()
,其他兩個slice()
和substring()
都是代表截取的結束位置都只接收一個參數的情況下,都是從起始位置一致截取到末尾
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()
的話,不會對兩個參數進行對比,如果第一個參數大於第二個參數,會直接返回空字符串
總結
通過分析了他們在不同參數情況下的表現,最後把他們進行一個小小的總結:
相同點在文章開頭已經總結,接下來是區別:
slice()
兩個參數分別代表着截取的開頭和結尾,而substr()
的第二個參數則代表着截取的位數(即長度),substring()
先對兩個參數進行大小對比,再確定截取區域三個方法如果截取到末尾,便會停止截取,無論參數約定的結束位置、或約定的長度有多大。
當參數爲負數的情況:
slice()
會把負數與字符串的長度相加,得到的正數再執行代碼。substr()
第一個參數也是把負數與字符串的長度相加得到正數,第二個參數則會把負數轉爲0
。substring()
則會把所有負數參數轉爲0