SplitMatch(S, q, R) 接下来,我们需要了解一下SplitMatch(S, q, R)这个方法做了些什么事。这个方法在split规范中的下方有提及。它主要做的事是,根据分隔符(separator)的类型进行相应的操作: •如果分隔符是RegExp类型的,调用RegExp的内部方法[[Match]]来对字符串进行匹配,如果匹配失败,返回failure,否则,返回一个MatchResult类型的结果。 •如果分隔符是字符串,进行匹配判断,失败返回failure,成功返回MatchResult类型的结果。
MatchResult 上面的步骤中又引出了一个MatchResult类型的变量。通过查文档发现,该类型的变量有两个属性endIndex和captures,endIndex的值是字符串匹配的位置加上1,captures可以理解为一个数组,当分隔符为正则表达式时,它里面的元素是分组捕获的值;当分隔符为字符串时,它为一个空数组。 接下来 我们从上面的步骤可以看出,分割的字符串是在截取字符串这一步骤中产生的(正则表达式的分组捕获除外)。它的作用是截取指定开始(包含在内)和结束位置(不包含在内)之间的字符串,那它什么时候会返回""呢?有一种特殊情况是开始位置和结束位置的值相等,这只是猜想而已,因为该规范没有给出截取字符串的规范步骤。 都走到这里了,为什么不再往前走一步呢? 于是,我试着搜索了一些V8的源码,看看能不能找到具体的实现方法。确实找到了相关的代码,源码链接 这里摘取其中一部分: 复制代码 代码如下: function StringSplitJS(separator, limit) { ... ... //分隔符是字符串的情况 if (!IS_REGEXP(separator)) { var separator_string = TO_STRING_INLINE(separator); if (limit === 0) return []; // ECMA-262 says that if separator is undefined, the result should // be an array of size 1 containing the entire string. if (IS_UNDEFINED(separator)) return [subject]; var separator_length = separator_string.length; //分隔符是空字符串,直接返回了字符数组 if (separator_length === 0) return %StringToArray(subject, limit); var result = %StringSplit(subject, separator_string, limit); return result; } if (limit === 0) return []; // 分隔符是正则表达式的情况,调用StringSplitOnRegExp return StringSplitOnRegExp(subject, separator, limit, length); } //此处省略若干代码