# Strings
## `String.prototype.*`
None of the string methods modify `this` – they always return fresh strings.
* `charAt(pos: number): string` ES1
Returns the character at index `pos`, as a string (JavaScript does not have a datatype for characters). `str[i]` is equivalent to `str.charAt(i)` and more concise (caveat: may not work on old engines).
```repl
> 'abc'.charAt(1)
'b'
```
* `charCodeAt(pos: number): number` ES1
Returns the 16-bit number (0–65535) of the UTF-16 code unit (character) at index `pos`.
```repl
> 'abc'.charCodeAt(1)
98
```
* `codePointAt(pos: number): number | undefined` ES6
Returns the number of the Unicode code point of the 1–2 characters at index `pos`. If there is no such index, it returns `undefined`.
* `concat(...strings: string[]): string` ES3
Returns the concatenation of `this` and `strings`. `'a'+'b'` is equivalent to `'a'.concat('b')` and more concise.
```repl
> 'ab'.concat('cd', 'ef', 'gh')
'abcdefgh'
```
* `endsWith(searchString: string, endPos=this.length): boolean` ES6
Returns `true` if `this` ends with `searchString` at index `endPos` and `false`, otherwise.
```repl
> 'foo.txt'.endsWith('.txt')
true
> 'abc'.endsWith('ab', 2)
true
```
* `includes(searchString: string, startPos=0): boolean` ES6
Returns `true` if `this` contains the `searchString` and `false`, otherwise. The search starts at `startPos`.
```repl
> 'abc'.includes('b')
true
> 'abc'.includes('b', 2)
false
```
* `indexOf(searchString: string, minIndex=0): number` ES1
Returns the lowest index at which `searchString` appears within `this`, or `-1`, otherwise. Any returned index will be `minIndex` or higher.
```repl
> 'abab'.indexOf('a')
0
> 'abab'.indexOf('a', 1)
2
> 'abab'.indexOf('c')
-1
```
* `lastIndexOf(searchString: string, maxIndex=Infinity): number` ES1
Returns the highest index at which `searchString` appears within `this`, or `-1`, otherwise. Any returned index will be `maxIndex` or lower.
```repl
> 'abab'.lastIndexOf('ab', 2)
2
> 'abab'.lastIndexOf('ab', 1)
0
> 'abab'.lastIndexOf('ab')
2
```
* `match(regExp: string | RegExp): RegExpMatchArray | null` ES3
If `regExp` is a regular expression with flag `/g` not set then `.match()` returns the first match for `regExp` within `this`. Or `null` if there is no match. If `regExp` is a string, it is converted to a regular expression before performing the previous steps.
The result has the following type:
```js
interface RegExpMatchArray extends Array {
index: number;
input: string;
groups: undefined | {
[key: string]: string
};
}
```
Numbered capture groups become Array indices. [Named capture groups](http://exploringjs.com/es2018-es2019/ch_regexp-named-capture-groups.html) (ES2018) become properties of `.groups`. In this mode, `.match()` works like `RegExp.prototype.exec()`.
Examples:
```repl
> 'ababb'.match(/a(b+)/)
[ 'ab', 'b', index: 0, input: 'ababb', groups: undefined ]
> 'ababb'.match(/a(?b+)/)
[ 'ab', 'b', index: 0, input: 'ababb', groups: { foo: 'b' } ]
> 'abab'.match(/x/)
null
```
* `match(regExp: RegExp): string[] | null` ES3
If flag `/g` of `regExp` is set, `.match()` returns either an Array with all matches or `null` if there was no match.
```repl
> 'ababb'.match(/a(b+)/g)
[ 'ab', 'abb' ]
> 'ababb'.match(/a(?b+)/g)
[ 'ab', 'abb' ]
> 'abab'.match(/x/g)
null
```
* `normalize(form: 'NFC'|'NFD'|'NFKC'|'NFKD' = 'NFC'): string` ES6
Normalizes `this` according to [the Unicode Normalization Forms](https://unicode.org/reports/tr15/).
* `padEnd(len: number, fillString=' '): string` ES2017
Appends `fillString` to `this` until it has the desired length `len`.
```repl
> '#'.padEnd(2)
'# '
> 'abc'.padEnd(2)
'abc'
> '#'.padEnd(5, 'abc')
'#abca'
```
* `padStart(len: number, fillString=' '): string` ES2017
Prepends `fillString` to `this` until it has the desired length `len`.
```repl
> '#'.padStart(2)
' #'
> 'abc'.padStart(2)
'abc'
> '#'.padStart(5, 'abc')
'abca#'
```
* `repeat(count=0): string` ES6
Returns a string that is `this`, repeated `count` times.
```repl
> '*'.repeat()
''
> '*'.repeat(3)
'***'
```
* `replace(searchValue: string | RegExp, replaceValue: string): string` ES3
Replace matches of `searchValue` with `replaceValue`. If `searchValue` is a string, only the first verbatim occurrence is replaced. If `searchValue` is a regular expression without flag `/g`, only the first match is replaced. If `searchValue` is a regular expression with `/g` then all matches are replaced.
```repl
> 'x.x.'.replace('.', '#')
'x#x.'
> 'x.x.'.replace(/./, '#')
'#.x.'
> 'x.x.'.replace(/./g, '#')
'####'
```
Special characters in `replaceValue` are:
* `$$`: becomes `$`
* `$n`: becomes the capture of numbered group `n` (alas, `$0` does not work)
* `$&`: becomes the complete match
* `` $` ``: becomes everything before the match
* `$'`: becomes everything after the match
Examples:
```repl
> 'a 2018-04 b'.replace(/([0-9]{4})-([0-9]{2})/, '|$2|')
'a |04| b'
> 'a 2018-04 b'.replace(/([0-9]{4})-([0-9]{2})/, '|$&|')
'a |2018-04| b'
> 'a 2018-04 b'.replace(/([0-9]{4})-([0-9]{2})/, '|$`|')
'a |a | b'
```
[Named capture groups](http://exploringjs.com/es2018-es2019/ch_regexp-named-capture-groups.html) (ES2018) are supported, too:
* `$` becomes the capture of named group `name`
Example:
```repl
> 'a 2018-04 b'.replace(/(?[0-9]{4})-(?[0-9]{2})/, '|$|')
'a |04| b'
```
* `replace(searchValue: string | RegExp, replacer: (substr: string, ...args: any[]) => string): string` ES3
If the second parameter is a function occurrences are replaced with the strings it returns. Its parameters are:
* `all`: the complete match
* `g1`, `g2`, etc.: whatever was captured by numbered group 1, etc.
* `offset`: where was the match found in the input string?
* `string`: the whole input string
```repl
> 'a 2018-04 b'.replace(/([0-9]{4})-([0-9]{2})/, (all, year, month) => '|'+all+'|')
'a |2018-04| b'
```
[Named capture groups](http://exploringjs.com/es2018-es2019/ch_regexp-named-capture-groups.html) (ES2018) are supported, too. If there are any, a last parameter contains an object whose properties contain the captures:
```repl
> const replacer = (...args) => { const groups=args.pop(); return '|'+groups.month+'|' };
> 'a 2018-04 b'.replace(/(?[0-9]{4})-(?[0-9]{2})/, replacer)
'a |04| b'
```
* `search(regExp: string | RegExp): number` ES3
Returns the index at which `regExp` occurs within `this`. If `regExp` is a string, it is converted to a regular expression.
```repl
> 'a2b'.search(/[0-9]/)
1
> 'a2b'.search('[0-9]')
1
```
* `slice(start=0, end=this.length): string` ES3
Returns the substring of `this` that starts at (including) index `start` and ends at (excluding) index `end`. You can use negative indices where `-1` means `this.length-1` (etc.).
```repl
> 'abc'.slice(1, 3)
'bc'
> 'abc'.slice(1)
'bc'
> 'abc'.slice(-2)
'bc'
```
* `split(separator: string | RegExp, limit?: number): string[]` ES3
Splits `this` into an Array of substrings – the strings that occur between the separators. The separator can either be a string or a regular expression. Captures made by groups in the regular expression are included in the result.
```repl
> 'abc'.split('')
[ 'a', 'b', 'c' ]
> 'a | b | c'.split('|')
[ 'a ', ' b ', ' c' ]
> 'a | b | c'.split(/ *\| */)
[ 'a', 'b', 'c' ]
> 'a | b | c'.split(/( *)\|( *)/)
[ 'a', ' ', ' ', 'b', ' ', ' ', 'c' ]
```
* `startsWith(searchString: string, startPos=0): boolean` ES6
Returns `true` if `this` starts with `searchString` at index `startPos` and `false`, otherwise.
```repl
> '.gitignore'.startsWith('.')
true
> 'abc'.startsWith('bc', 1)
true
```
* `substring(start: number, end=this.length): string` ES1
Use `.slice()` instead of this method. `.substring()` wasn’t implemented consistently in older engines and doesn’t support negative indices.
* `toUpperCase(): string` ES1
Returns a copy of `this` in which all lowercase alphabetic characters are converted to uppercase. How well that works for various alphabets depends on the JavaScript engine.
```repl
> '-a2b-'.toUpperCase()
'-A2B-'
> 'αβγ'.toUpperCase()
'ΑΒΓ'
```
* `toLowerCase(): string` ES1
Returns a copy of `this` in which all uppercase alphabetic characters are converted to lowercase. How well that works for various alphabets depends on the JavaScript engine.
```repl
> '-A2B-'.toLowerCase()
'-a2b-'
> 'ΑΒΓ'.toLowerCase()
'αβγ'
```
* `trim(): string` ES5
Returns a copy of `this` in which all leading and trailing whitespace is removed.
```repl
> '\r\n# \t'.trim()
'#'
```
## More information
* String methods of various ECMAScript versions in detail: http://exploringjs.com
## Sources
* https://github.com/Microsoft/TypeScript/blob/master/lib/lib.es6.d.ts
* MDN
* ECMAScript spec