文章出處

這個系列的前面幾篇文章中有談到在一個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的相關方法有點古怪,小陌生,但同時也可以很強大。希望本文簡短的介紹對你在日常開發中有所幫助。 感謝您的閱讀,文中不妥之處還望批評指正。如果你感覺本文對你有所幫助,請點贊!

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()