欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6 字符串方法includes(), startsWith(), endsWith()详解

程序员文章站 2022-03-01 14:53:32
...

最近准备把阮一峰大神的ECMAScript6入门教程通学一遍,于是便开始了填坑之旅。。。当我看到 第四章--字符串的扩展 的时候发现es6新增了如下三个方法:

  • includes():返回布尔值,表示是否找到了参数字符串。
  • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true

这里大家都懂,不在赘述。

但是,以上三个方法都支持第二个参数,表示开始搜索的位置。

let s = 'Hello world!';

s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false

"上面代码表示,使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。"--原文是这样说的。

但是细细琢磨,真的是这样吗?

不知道是不是作者笔误,如果把原文中的endsWith改为startsWith还可以说通,所以作者原意应该是“使用第二个参数n时,startsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。

我们来验证一下:

1.s.startsWith('world',6),)针对的是'world'位置的前6个字符,即'Hello '这六个字符。

我们看一下polyfill兼容性源码:

if (!String.prototype.startsWith) {
	String.prototype.startsWith = function(search, pos) {
		return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
	};
}

可以看到当传入的第二个参数pos为空或<0的值时,他会从s(要判断的字符串)初始位置截取search.length个长度的字符串,否则从pos位置开始截取search.length个长度的字符串。然后与search做比较得出结论。可以看到只要search的位置在str的pos位置上,返回值总为true,所以我们可以理解startsWith判断s中search的前pos个字符一定为true。同理可得

s.startsWith("world",7)    //false

s.startsWith("orld",7)    // true

s.startsWith("rld",8)    // true

s.startsWith("ld",9)    // true

2.s.endsWith('Hello',5),判断的是'Hello'后面的字符,即' world!'这7个字符。

看一下polyfill兼容性源码:

if (!String.prototype.endsWith) {
	String.prototype.endsWith = function(search, pos) {
		if (pos === undefined || pos > this.length) {
			pos = this.length;
		}
		return this.substring(pos - search.length, pos) === search;
	};
}

可以看到当传入的第二个参数pos为undefined或>s的总长度时,他会从s(要判断的字符串)截取pos-search.lengh到pos位置的字符串,然后判断其截取到的字符串是否与search相等。不难得出只要search的位置在str的(pos-search)位置上,返回值总为true,所以endsWith判断s中从pos位置直到字符串结束的字符一定为true。同理可得

s.endsWith('Hello')    // false

s.endsWith('ello',5)     // true

s.endsWith('llo',5)     // true

s.endsWith('lo',5)     // true

3. s.includes("Hello",6)为什么为false

看一下polyfill兼容性源码:

if (!String.prototype.includes) {
  String.prototype.includes = function(search, pos) {
    'use strict';
    if (typeof pos !== 'number') {
      pos = 0;
    }
    
    if (pos + search.length > this.length) {
      return false;
    } else {
      return this.indexOf(search, pos) !== -1;
    }
  };
}

可以看到只有 pos+search.length 不能大于 s.length 而且 search 的位置>=pos才会返回true.

s.includes("Hello",0)    // true

s.includes("Hello",1)    // false

s.includes("Hello",6)    // false "Hello"的位置为0  < 6肯定为false 了

致此,希望大家对这些方法有个清晰的认识。