這個系列的前面幾篇文章中有談到在一個Object上使用apply、call等方法操作另一個Object的方法,今天我們來學習怎么樣在String上調用Array相關方法。 在許多方面,字符串表現的好像字符數組,許多Javascript array相關方法也可以使用在String類型上,但是并不是所有的方法都可以。看下面示例:
var name = "Benjamin"; //Outputs: TypeError: [].push.call(...) is read-only [].push.call(name, "is my name");
報錯:提示Javascript中字符串是只讀的,因此任何方法想改變字符串都將失敗,因此可以排除掉數組的push、pop、shift、unshift、splice方法。 但是仍有一些數組的方法是可以使用在字符串上的,看下例:
var name = "Benjamin"; var res01 = [].some.call(name, function(val, index, arr) { //Outputs:String {0: "B", 1: "e", 2: "n", 3: "j", 4: "a", 5: "m", 6: "i", 7: "n", length: 8} console.log(arr); return val === "B"; }); var res02 = [].every.call(name, function(val, index, arr) { return val === "B"; }); var res03 = [].filter.call(name, function(val, index, arr) { return val < "e"; }); //Outputs: true console.log(res01); //Outputs: false console.log(res02); //Outputs: ["B", "a"] console.log(res03);
詳細了解some,every,filter方法的使用,請戳:Javascript Array.prototype.some(),Javascript Array.prototype.every(),Javascript Array.prototype.filter(),在字符串上操作數組方法是不是感覺挺棒的,但是大家要注意到filter方法返回的是一個數組,而不是一個字符串,而arr的輸出值為一個json對象。但是細細想想,這也是有道理的,call和apply方法不會改變函數的邏輯,只改變它操作的值。 但是如果上例的filter方法需要我們返回字符串,我們可以使用鏈式操作:
var name = "Benjamin"; var res03 = [].filter.call(name, function(val, index, arr) { return val < "e"; }).join(""); //Outputs: ["B", "a"] console.log(res03);
從上面來看,String是不能操作Array上的某些方法,但是我們該如何解決呢?解決此問題有一個相當簡單的方式:我們可以先把字符串轉換為字符數組,然后再轉換為字符串。
var name = "Benjamin", //TypeError: [].reverse.call(...) is read-only //res01 = [].reverse.call(name), res02 = [].slice.call(name).reverse().join(""); //Outputs: ["B", "e", "n", "j", "a", "m", "i", "n"] console.log([].slice.call(name)); //Outputs: ["n", "i", "m", "a", "j", "n", "e", "B"] console.log([].slice.call(name).reverse()); //console.log(res01); // Outputs: nimajneB console.log(res02);
res01處如果放開也會報read-only錯誤,關于slice方法的使用看看MDN的描述:
slice 不修改原數組,只會返回一個包含了原數組中提取的部分元素的一個新數組。原數組的元素會按照下述規則被拷貝("一級深拷貝"[one level deep]規則):
如果該元素是個對象引用 (不是實際的對象),slice 會拷貝這個對象引用到新的數組里。兩個對象引用都引用了同一個對象。
如果被引用的對象發生改變,則改變將反應到新的和原來的數組中。 對于字符串和數字來說(不是 String 和 Number 對象),slice 會拷貝字符串和數字到新的數組里。在一個數組里修改這些字符串或數字,不會影響另一個數組。
如果向兩個數組任一中添加了新元素,則另一個不會受到影響。
我們直接使用[].reverse.call轉換沒有成功,而借助slice方法來轉換成字符串數組,并對其使用revserse方法,然后使用join方法再轉換為字符串。 從上面的描述,有么有感覺到在String上使用Array的相關方法有點古怪,小陌生,但同時也可以很強大。希望本文簡短的介紹對你在日常開發中有所幫助。 感謝您的閱讀,文中不妥之處還望批評指正。如果你感覺本文對你有所幫助,請點贊!
文章列表