这是我参与更文挑战的第4天,活动详情查看: 更文挑战
String
获取单个字符
let str = "abcdef";
str.charAt(1) == str[1] // true "b"
str.charAt() // "a"
str.charAt(6) // ""
这里str虽然是原始类型的,但是依然可以像对象一样调用方法。在调用方法的时候,进行了三步操作。
- 创建一个String类型的实例;
- 调用实例上的特定方法;
- 销毁实例
let str = "abcdef";
str.length // 6
str.length = 2;
str.length // 6
不是对str本身操作的,是对新创建的实例操作的,但实例创建完就销毁了。
const obj = {
toString() { return 1; }
}
let str = "abcdefg";
str[obj] == "b"; // true
let arr = [1,2,3,4];
str[obj] == 2; // true
[]内会调用String()转型函数。
字符串不可变
字符串是原始类型的,所以自身是没有属性的,当原始值调用属性时,会发生自动包装机制,创建一个原始类型对应的包装类,调用完属性再销毁,一般用来读取属性值,而非修改,修改也没有意义。
let str = "abcd";
str.length; // 4
str.length = 3
str.length; // 4
str.name = "alphabet";
str.name; // undefined
// ----------------------------------------
let strObj = new String("abcd");
strObj.length = 2;
strObj.length; // 4
String对象中的length属性是不能改写的。也就是说,字符串是不可变的,一旦创建值就不能改变,要修改某个变量中的字符串值,必须先销毁原始的字符串,再把新的字符串保存到该变量上。
console.log(strObj);
// String {"abcd"}
// 0: "a"
// 1: "b"
// 2: "c"
// 3: "d"
// length: 4
String对象是原生类数组。只不过length属性不能改变。
String静态方法
String.fromCharCode()
输入一个或多个Unicode编码,返回对应的字符。
String.fromCharCode(65, 66, 67, 68); // "ABCD"
String.fromCharCode(32) // " " 空格
String.fromCharCode(9) // " " 制表符
String实例方法
在String.prototype上
charCodeAt()
返回字符串对应索引位置的字符的Unicode码。
let str = "abc";
str.codeCharAt(1);
// b的unicode码是98
concat()
连接两个字符串文本,并返回一个新的字符串。不影响原来的字符串。
let str = "123";
let s1 = "456";
let s2 = "789";
let s3 = "ABC";
let newStr = str.concat(s1,s2,s3);
// "123456789ABC"
拼接之前,会将参数转换成字符串形式。
不建议使用,强烈建议使用赋值操作符(+, +=)代替 concat 方法。
includes()
判断一个字符串是否包含另外一个字符串。区分大小写。
str.includes(searchString[, position])
searchString参数在判断之前会被转换成字符串。
position是可选参数,从当前字符串的哪个索引位置开始搜寻子字符串,默认值为 0。
endsWith()
确定一个字符串是否在另一个字符串的末尾。区分大小写。
String.prototype.endsWith = function(search, this_len) {
// search 要搜索的字符串
// this_len 被搜索的字符串的长度,可以控制哪个是末尾
if (this_len === undefined || this_len > this.length) {
this_len = this.length;
}
// 从末尾截取要搜索字符串的长度,然后和搜索字符串进行比较。返回布尔值。
return this.substring(this_len - search.length, this_len) === search;
};
let str = "endsWith";
let b = str.endsWith("With"); // true
startsWith()
确定一个字符串是否在另一个字符串的开头。区分大小写。
if (!String.prototype.startsWith) {
Object.defineProperty(String.prototype, 'startsWith', {
value: function(search, pos) {
// 这一串有点东西
pos = !pos || pos < 0 ? 0 : +pos;
// 从指定位置开始截取,截取给定字符串的长度。进行比较。
return this.substring(pos, pos + search.length) === search;
}
});
}
indexOf()
返回调用它的String对象中第一次出现的指定值searchValue的索引,从 fromIndex 处进行搜索。如果未找到该值,则返回 -1。
str.indexOf(searchValue [, fromIndex])
详见MDN,太细了。
lastIndexOf()
返回调用String对象的指定值最后一次出现的索引,在一个字符串中的指定位置 fromIndex处从后向前搜索。如果没找到这个特定值则返回-1 。
padEnd()
在当前字符串尾部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。
if (!String.prototype.padEnd) {
// targetLength 理想字符串的长度。
// padString 替补字符串,不到理想状态,拿这个补齐。
String.prototype.padEnd = function padEnd(targetLength,padString) {
// 因为>>是运算符,会用Number进行转化。如果是NaN就会转换成0。
// 也就是说,不是数字就转换成0,是数字就原值返回。
targetLength = targetLength>>0;
// 检查传入的padString参数,如果没传就返回 空格字符串,如果传了就转换成字符串。
padString = String((typeof padString !== 'undefined' ? padString: " ")); // 空格字符串的长度为一
// 如果this(当前字符串)已经是理想长度了,直接返回,不用处理。
if (this.length > targetLength) {
return String(this);
}
else {
// 查看还缺几个字符。
targetLength = targetLength - this.length;
// 如果理想字符数量比替补字符串还要多的话,就重复替补字符串。
if (targetLength > padString.length) {
// 计算要重复的次数,并增加到替补字符串上。
padString += padString.repeat(targetLength/padString.length);
}
// 拼接字符串,根据之前算出来还缺几个字符,截取替补字符串。
return String(this) + padString.slice(0,targetLength);
}
};
}
"1".padEnd(3);
// "1 "
不传第二参数时,默认是空格字符串。
padStart()
在当前字符串头部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。
let hour = 9;
let min = 3;
let s = 45;
function format(time) {
return String(time).padStart(2, "0");
}
let time = `${format(hour)}:${format(min)}:${format(s)}`
// 09:03:45
repeat()
指定某个字符串,重复多少次,返回一个新的字符串。
let str = "1";
str.repeat(4);
// "1111"
重复后的字符串长度不超过,1 << 28 这么长,因为大部分浏览器不支持这么长。
slice()
提取字符串的某一部分,返回新字符串,不会改动原字符串。
str.slice(beginIndex[, endIndex])
beginIndex表示从哪个索引位置开始,endIndex表示在哪个索引位之前结束。
参数支持负数。
如果参数是负数,会进行strLength + beginIndex的处理,strLength表示调用函数的字符串长度。
let str = "1234";
str.slice(1,3);
// "23"
从字符串索引1开始,到索引3之前结束。
其实就是,从索引1开始,截取(3 - 1)个字符。
str.slice(-2,-1);
// "3"
会转换成,str.slice((-2 + 4), (-1 + 4)),从倒数第二个开始,截取(-1 - -2)个字符。
str.slice(1,-1);
// "23"
从索引1开始到倒数第一个字符前结束。
str.slice(2);
// "34"
str.slice(2,100);
// "34"
str.slice(2,1);
// ""
str.slice(2,-100);
// ""
如果endIndex结束索引没有或者超出字符串长度,就从开始索引返回全部字符串。
如果是不服逻辑的索引,则返回空字符串。
str.slice(-100);
// "1234"
str.slice(-100, 2);
// "12"
str.slice(-100, -100);
// ""
beginIndex如果为负数,加上strLength还是为负数的话,就变为0处理。
str.slice(NaN);
// "1234"
str.slice(null);
// "1234"
str.slice(true);
// "234"
str.slice("abc");
// "1234"
传入的两个参数都会调用Number()进行转型,如果是NaN就当作0处理。
str.slice(0, 1.1);
// "1"
str.slice(0, "1.9");
// "1"
会先转换成数字类型,再转换成整型。向下取整。
substring()
和slice类似,提取字符串的某一部分,返回新字符串,不会改动原字符串。
str.substring(indexStart[, indexEnd])
参数不支持负数,负数会当作0处理。
注意事项:
- 如果
indexStart等于indexEnd,substring返回一个空字符串。 - 如果省略
indexEnd,substring提取字符一直到字符串末尾。 - 如果任一参数小于 0 或为
NaN,则被当作 0。 - 如果任一参数大于
stringName.length,则被当作stringName.length。 - 如果
indexStart大于indexEnd,则substring的执行效果就像两个参数调换了一样。见下面的例子。
let str = "abcdefg";
// 输出 "abc"
str.substring(0,3);
str.substring(3,0);
str.substring(3,-3);
str.substring(3,NaN);
str.substring(-2,3);
str.substring(NaN,3);
// 输出 "efg"
str.substring(4,7);
str.substring(7,4);
// 输出 ""
str.substring(4,4);
// 输出 "abcdef"
str.substring(0,6);
// 输出 "abcdefg"
str.substring(0,7);
str.substring(0,10);
先把小于0和为NaN的参数替换成0,再把大于字符串长度的参数替换成字符串长度,比较两参数,前一个参数大于后一个参数时就交换它们的位置。
substr()
与slice和substring略有不同,第二个参数表示截取的个数。不改变原字符串。
str.substr(start[, length])
start表示从哪个索引位置开始,length表示往后截取几个字符。
第一个参数支持负数。
start为负数时,被看作strLength + start处理。
注意事项:
- 如果
start为正值,且大于或等于字符串的长度,则substr返回一个空字符串。 - 如果
start为负值,则substr把它作为从字符串末尾开始的一个字符索引。 - 如果
start为负值且abs(start)大于字符串的长度,则当作0处理。 - 如果
length为 0 或负值,则substr返回一个空字符串。 - 如果忽略
length,则substr提取字符,直到字符串末尾。
let str = "abcdefghij";
str.substr(1,2);
// "bc"
str.substr(-3,2);
// "hi"
str.substr(-3);
// "hij"
str.substr(1);
// "bcdefghij"
str.substr(-20,2);
// "ab"
str.substr(20,2);
// ""
toUpperCase()
返回一个全是大写形式的字符串。不改变原字符串。
当你将其上下文 this 值设置为非字符串类型,会将任何非字符串类型的值转为字符串。
const a = String.prototype.toUpperCase.call({
toString: function toString() {
return 'abcdef';
}
});
// "ABCDEF"
const b = String.prototype.toUpperCase.call(true);
// "TRUE"
toLowerCase()
和toUpperCase相反,返回一个全是小写形式的字符串。
split()
把字符串按照指定的形式拆分成数组。
let str = "1,2,3,4,5,6";
let arr = str.split(",");
// [1, 2, 3, 4, 5, 6]
let str = "123456";
str.split("");
// [1,2,3,4,5,6]
直接拆分把字符串的每一位放入数组。
let str = "abcd";
str.split();
// ["acbd"]
不传参数,或参数不符合要求都会将其本身放入数组。
trim()
去掉字符串左右两端的空白字符。