ES6
String extension
Example methods: includes(), startsWith(), endsWith()
Traditionally, JavaScript has only had the indexOf method, which can be used to determine whether one string is contained within another. ES6 offers three new approaches.
-
Includes () : Returns a Boolean value indicating whether the parameter string was found.
-
StartsWith () : Returns a Boolean value indicating whether the argument string is at the head of the original string.
-
EndsWith () : Returns a Boolean value indicating whether the argument string is at the end of the original string.
let s = 'Hello world! '; s.startsWith('Hello') // true s.endsWith('! ') // true s.includes('o') // trueCopy the code
All three of these methods support a second parameter indicating where the search begins.
let s = 'Hello world! '; s.startsWith('world', 6) // true s.endsWith('Hello', 5) // true s.includes('Hello', 6) // falseCopy the code
The code above shows that with the second argument n, endsWith behaves differently from the other two methods. It works for the first n characters, while the other two work from the NTH position up to the end of the string.
Instance method: repeat()
The repeat method returns a new string, repeating the original string n times.
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
Copy the code
The argument is rounded if it is a decimal.
'na'. Repeat (2.9) / / "nana"Copy the code
If the repeat argument is negative or Infinity, an error is reported.
'na'.repeat(Infinity)
// RangeError
'na'.repeat(-1)
// RangeError
Copy the code
However, if the argument is a decimal between 0 and -1, it is the same as 0 because the round is performed first. If the decimal number between 0 and -1 is rounded to -0, repeat is regarded as 0.
'na'. Repeat (0.9) / / ""Copy the code
The NaN argument is equal to 0.
'na'.repeat(NaN) // ""
Copy the code
If the argument of the repeat is a string, it is converted to a number first.
'na'.repeat('na') // ""
'na'.repeat('3') // "nanana"
Copy the code
Example methods: padStart(), padEnd()
ES2017(ES8) introduces the string completion length function. If a string is not of a specified length, the header or tail is completed. PadStart () is used for head completion and padEnd() for tail completion.
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
Copy the code
In the code above, padStart() and padEnd() take two arguments. The first argument is the maximum length that string completion takes effect, and the second argument is the string used for completion.
If the length of the original string is equal to or greater than the maximum length, the string completion does not take effect and the original string is returned.
'xxx'.padStart(2, 'ab') // 'xxx'
'xxx'.padEnd(2, 'ab') // 'xxx'
Copy the code
If the sum of the length of the completion string and the original string exceeds the maximum length, the completion string with more than bits is truncated.
'abc'.padStart(10, '0123456789')
// '0123456abc'
Copy the code
If the second argument is omitted, Spaces are used to complete the length by default.
'x'.padStart(4) // ' x'
'x'.padEnd(4) // 'x '
Copy the code
A common use of padStart() is to specify bits for numeric completion. The following code generates a 10-digit numeric string.
'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"
Copy the code
Another use is the prompt string format.
'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
Copy the code
Example methods: trimStart(), trimEnd()
ES2019(ES10) adds the trimStart() and trimEnd() methods for string instances. They behave in the same way as trim(), with trimStart() eliminating whitespace at the head of the string and trimEnd() eliminating whitespace at the end. They all return a new string and do not modify the original string.
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
Copy the code
In the code above, trimStart() removes only the header whitespace and preserves the trailing whitespace. TrimEnd () behaves similarly.
In addition to the space bar, these methods also work with invisible whitespace characters such as the TAB key at the beginning (or end) of the string, and newlines.
The browser also deploys two additional methods, trimLeft(), which is an alias for trimStart(), and trimRight(), which is an alias for trimEnd().
Example method: matchAll()
If a regular expression has more than one match in a string, it is now common to use the G or Y modifier to retrieve each match in a loop.
var regex = /t(e)(st(\d?) )/g; var string = 'test1test2test3'; var matches = []; var match; while (match = regex.exec(string)) { matches.push(match); } matches // [ // ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"], // ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"], // ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"] // ]Copy the code
ES2020 (ES11) increased String. Prototype. MatchAll () method, which can be a one-time remove all matching. However, it returns an Iterator, not an array.
In the code above, the while loop fetches the regular match for each of three rounds.
const string = 'test1test2test3'; const regex = /t(e)(st(\d?) )/g; for (const match of string.matchAll(regex)) { console.log(match); } // ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"] // ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"] // ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]Copy the code
MatchAll (regex) returns a traverser, so we can use for… Of loop out. The advantage of returning a traversal over an array is that the traversal is resource-efficient if the result of the match is a large array.
Iterator to array is very simple, using… The operator and array.from () method do the trick.
[... string.matchall (regex)] array. from(string.matchall (regex))Copy the code
Instance method: replaceAll()
Historically, the instance method replace() of a string could only replace the first match.
'aabbcc'.replace('b', '_')
// 'aa_bcc'
Copy the code
In the example above, replace() simply replaces the first b with an underscore.
If you want to replace all matches, you have to use the g modifier of the regular expression.
'aabbcc'.replace(/b/g, '_')
// 'aa__cc'
Copy the code
Regular expressions aren’t that convenient and intuitive after all, and ES2021(ES12) introduces the replaceAll() method, which replaces all matches at once.
'aabbcc'.replaceAll('b', '_')
// 'aa__cc'
Copy the code
It is used in the same way as replace(), returning a new string without changing the original string.
String.prototype.replaceAll(searchValue, replacement)
Copy the code
In the above code, the searchValue is the search mode, which can be either a string or a global regular expression (with the G modifier).
If the searchValue is a regular expression without the G modifier, replaceAll() will report an error. This is different from replace().
/ / no error 'aabbcc. Replace (a/b /,' _ ') / / error 'aabbcc replaceAll (a/b /,' _ ')Copy the code
In the example above, /b/ without the g modifier causes replaceAll() to fail.
The second argument to replaceAll(), replacement, is a string representing the text of the replacement, where special strings can be used.
- $& : Matching substring.
- $’ : Matches the text before the result.
- $’ : the text following the match result.
- $n: the NTH group of contents to be matched successfully. N is a natural number starting from 1. This parameter is valid only if the first parameter is a regular expression.
- $$: indicates the dollar sign $.
Here are some examples.
'abbc'. ReplaceAll ('b', '$&') // 'abbc' // $' indicates the string before the matching result // For the first 'b', $` refer to ` ` / / for the second ` b `, $` refer to ` ab ` 'abbc'. The replaceAll (' b ', '$`') / / / / 'aaabc' $' said after the match results / / on the first string ` ` b, $' refer to ` BC ` / / for the second ` `, b $' refer to ` ` c. 'abbc replaceAll (' b', ` $' `) / / abccc '/ / $1 said first group match, regular expressions refer to ` ab ` / / $2 said the second group match of the regular expression, Refer to ` BC ` 'abbc. ReplaceAll (/ (ab)/g (BC),' $2 $1 ') / / / / 'bcab' refer to the $$$' ABC '. The replaceAll (' b ', '$$') / /' a $c 'Copy the code
In addition to being a string, the second argument to replaceAll() can be a function whose return value replaces the text matched by the first argument searchValue.
'aabbcc'.replaceAll('b', () => '_')
// 'aa__cc'
Copy the code
In the example above, the second argument to replaceAll() is a function that returns a value that replaces all matches of b.
Numerical extension
-
Number.isfinite () : number.isfinite () is used to check whether a Number isFinite, i.e., not Infinity.
-
Number.isnan () : used to check whether a value isNaN.
-
Number.parseint () : the same as the global method parseInt.
-
Number.parsefloat () : used with the global method parseFloat.
-
Number.isinteger () : Used to determine whether a value is an integer.
-
EPSILON: ES6 adds a tiny constant Number.EPSILON to the Number object. According to the specification, it represents the difference between 1 and the smallest floating point number greater than 1.
-
Number.issafeinteger () : Used to determine whether an integer falls within this range. The range of integers that JavaScript can accurately represent is between -2^53 and 2^53 (excluding the two endpoints), beyond which this value cannot be accurately represented.
Math object extension
-
Math.trunc() : The math.trunc method is used to remove the fractional part of a number and return the integer part.
-
Math.sign() : the math.sign method is used to determine whether a number is positive, negative, or zero. For non-numeric values, they are converted to numeric values first.
-
Math.cbrt() : Used to calculate the cube root of a number.
-
Math.hypot() : Returns the square root of the sum of squares of all parameters.
Extension of a function
Default values for function arguments
ES6 allows you to set default values for function arguments, which are written directly after the parameter definition.
function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
Copy the code
function Point(x = 0, y = 0) {
this.x = x;
this.y = y;
}
const p = new Point();
p // { x: 0, y: 0 }
Copy the code
Used in conjunction with destructively assigned default values
Parameter defaults can be used in conjunction with the default values of deconstructed assignments.
function foo({x, y = 5}) {
console.log(x, y);
}
foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined
Copy the code
function foo({x, y = 5} = {}) {
console.log(x, y);
}
foo() // undefined 5
Copy the code
The following two methods set default values for function arguments. The difference is that the default values of function arguments are empty objects, but the default values of object deconstruction assignment are set. The default value of the two function arguments is an object with specific properties, but the default value of the object’s destruct assignment is not set.
Function m1({x = 0, y = 0} = {}) {return [x, y]; } / / writing function 2 m2 ({x, y} = {x: 0, y: 0}) {return (x, y); }Copy the code
The following output is displayed:
/ / function without parameters (m1) / / [0, 0] m2 () / / [0, 0] / / x and y values of m1 (8} {x: 3, y:) / / [3, 8] m2 ({x: 3, y: 8}) / / [3, 8] / / x has the value, y no value of m1 (3} {x:) / / [3, 0] m2 (3} {x:) / / [3, undefined] / / x and y are no value of m1 ({}) / / (0, 0); m2({}) // [undefined, undefined] m1({z: 3}) // [0, 0] m2({z: 3}) // [undefined, undefined]Copy the code
The position of the default value
In general, the parameter that defines the default value should be the last parameter of the function. Because it’s easier to see what parameters are being omitted. If non-trailing arguments are set to default values, they cannot be omitted.
Function f(x = 1, y) {return [x, y]; } f () / / [1, undefined] f (2) / / [2, undefined] f (1) / / an error f (undefined, 1) / / [1, 1] / / the function f (x, y = 5, z) { return [x, y, z]; } f () / / / undefined ", undefined, 5 f (1) / / [1, 5, undefined] f (1, 2) / / an error f (1, undefined, 2) / / [1, 5, 2)Copy the code
None of the arguments with default values in the code above are tail arguments. In this case, you cannot omit this parameter without the argument that follows it, unless you explicitly enter undefined.
If undefined is passed, the parameter is triggered to equal the default value; null has no effect.
function foo(x = 5, y = 6) {
console.log(x, y);
}
foo(undefined, null)
// 5 null
Copy the code
In the above code, the x parameter corresponds to undefined, which triggers the default value, and the y parameter equals null, which does not trigger the default value.
The length property of the function
When a default value is specified, the length property of the function returns the number of arguments for which no default value is specified. That is, the length attribute is distorted when a default value is specified.
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
Copy the code
In the code above, the return value of the length attribute is equal to the number of arguments to the function minus the number of arguments to which the default value is specified. For example, the last function above defines three arguments, one of which c specifies the default value, so the length property is equal to 3 minus 1, resulting in 2.
This is because the length attribute means that the function expects the number of arguments to be passed. When a parameter specifies a default value, it is not included in the expected number of parameters passed. Similarly, the rest parameters below do not count toward the Length attribute.
(function(... args) {}).length // 0Copy the code
If the parameter to which the default value is set is not the last parameter, the length attribute does not count toward subsequent parameters.
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
Copy the code
scope
Once the default values of parameters are set, the parameters form a separate context when the function is declared initialized. After initialization, the scope will disappear. This syntactic behavior does not occur if the parameter defaults are not set.
var x = 1;
function f(x, y = x) {
console.log(y);
}
f(2) // 2
Copy the code
In the code above, the default value of parameter y is equal to variable x. When f is called, the arguments form a separate scope. In this scope, the default variable x refers to the first parameter x, not the global variable x, so the output is 2.
let x = 1;
function f(y = x) {
let x = 2;
console.log(y);
}
f() // 1
Copy the code
In the above code, the function f is called with the argument y = x forming a separate scope. In this scope, the variable x itself is undefined, so it points to the outer global variable x. When a function is called, the local variable x inside the function body does not affect the default variable x.
If the global variable x does not exist at this point, an error is reported.
function f(y = x) {
let x = 2;
console.log(y);
}
f() // ReferenceError: x is not defined
Copy the code
If I write it this way, I’ll get an error.
var x = 1;
function foo(x = x) {
// ...
}
foo() // ReferenceError: x is not defined
Copy the code
In the code above, the parameter x = x forms a separate scope. Instead, let x = x is executed. Due to the temporary dead zone, this line of code will report an error “x undefined”.
If the default value of an argument is a function, the scope of that function also follows this rule.
let foo = 'outer';
function bar(func = () => foo) {
let foo = 'inner';
console.log(func());
}
bar(); // outer
Copy the code
In the above code, the default value of func to the function bar is an anonymous function that returns the variable foo. Foo is not defined in the separate scope of the function argument, so foo refers to the outer global variable foo, so it prints outer.
If written as follows, an error is reported.
function bar(func = () => foo) {
let foo = 'inner';
console.log(func());
}
bar() // ReferenceError: foo is not defined
Copy the code
In the code above, foo in the anonymous function refers to the outer layer of the function, but the outer layer of the function does not declare the variable foo, so an error is reported.
Here is a more complicated example.
var x = 1;
function foo(x, y = function() { x = 2; }) {
var x = 3;
y();
console.log(x);
}
foo() // 3
x // 1
Copy the code
In the code above, the arguments to function foo form a single scope. In this scope, we first declare the variable x, then we declare the variable y, and the default value of y is an anonymous function. The variable x inside this anonymous function points to the first parameter x of the same scope. The internal variable x is declared inside the function foo. This variable is not the same as the first parameter x because it is not in the same scope. Therefore, the internal variable x and the external global variable x are not changed after y.
If var x = 3 is removed, foo’s internal variable x points to the first argument x, which is the same as the anonymous function’s internal x, so the final output is 2, while the outer global variable x remains intact.
var x = 1;
function foo(x, y = function() { x = 2; }) {
x = 3;
y();
console.log(x);
}
foo() // 2
x // 1
Copy the code
Rest parameters
ES6 introduces the REST parameter (of the form… Variable name), used to get extra arguments to a function so you don’t need to use the arguments object. The rest argument goes with a variable that puts the extra arguments into an array.
function add(... values) { let sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10Copy the code
The add function in the above code is a summation function that can be passed any number of arguments using the REST argument.
Here is an example of a REST parameter instead of the arguments variable.
/ / the arguments written variable function sortNumbers () {return Array. Prototype. Slice. The call (the arguments). The sort (); } // rest const sortNumbers = (... numbers) => numbers.sort();Copy the code
Comparing the two ways of writing the code above, you can see that the rest parameter is written more naturally and concisely.
Note: The REST parameter cannot be followed by any other parameter (that is, only the last parameter), otherwise an error will be reported.
Function f(a,... b, c) { // ... }Copy the code
The length property of the function, excluding the REST argument.
(function(a) {}).length // 1 (function(... a) {}).length // 0 (function(a, ... b) {}).length // 1Copy the code
Arrow function
Basic usage
ES6 allows functions to be defined using arrows (=>).
var f = v => v; Var f = function (v) {return v; };Copy the code
If the arrow function requires no arguments or more than one argument, use a parenthesis to represent the argument part.
var f = () => 5; Var f = function () {return 5}; var sum = (num1, num2) => num1 + num2; Var sum = function(num1, num2) {return num1 + num2; };Copy the code
If the arrow function has more than one statement in its code block, enclose them in braces and return them with a return statement.
var sum = (num1, num2) => { return num1 + num2; }
Copy the code
Because braces are interpreted as blocks of code, if an arrow function returns an object directly, it must enclose braces around the object or an error will be reported.
Let getTempItem = id => {id: id, name: "Temp"}; Let getTempItem = id => ({id: id, name: "Temp"});Copy the code
The following is a special case that, while running, gets the wrong result.
let foo = () => { a: 1 };
foo() // undefined
Copy the code
In the above code, the original intent is to return an object {a: 1}, but because the engine considers braces to be code blocks, it executes a line of statement A: 1. In this case, a can be interpreted as the label of the statement, so the actual statement executed is 1; , then the function ends with no return value.
If the arrow function has only one line and does not return a value, use the following notation instead of curly braces.
let fn = () => void doesNotReturn();
Copy the code
Arrow functions can be used in conjunction with variable destruction.
const full = ({ first, last }) => first + ' ' + last; Function full(person) {return person.first + "+ person.last; }Copy the code
One use of the arrow function is to simplify the callback function.
[1,2]. Map (function (x) {return x * x; }); [1,2,3]. Map (x => x * x);Copy the code
Here is an example of a REST parameter combined with an arrow function.
const numbers = (... nums) => nums; Numbers (1, 2,3,4,5) // Const headAndTail = (head,... tail) => [head, tail]; HeadAndTail (1, 2,3,4,5) // [2,3,4,5]Copy the code
Use caution points
The arrow function has several uses with caution.
-
The this object inside the function is the object at which it is defined, not used.
-
Should not be used as a constructor, that is, the new command should not be used, otherwise an error will be thrown.
-
You cannot use the Arguments object, which does not exist in the function body. If you do, use the REST argument instead.
-
Yield cannot be used, so arrow functions cannot be used as Generator functions.
The first of these four points is particularly noteworthy. The point of this object is mutable, but in arrow functions, it is fixed.
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
var id = 21;
foo.call({ id: 42 });
// id: 42
Copy the code
In the code above, the argument to setTimeout() is an arrow function that takes effect when foo is generated and will not execute until 100 milliseconds later. If it were a normal function, this would point to the global object Window and print 21. However, the arrow function causes this to always point to the object where the function definition is in effect ({id: 42} in this case), so it prints 42.
The arrow function can bind this in setTimeout to the scope in which it was defined, rather than pointing to the scope in which the runtime was defined. Here’s another example.
function Timer() { this.s1 = 0; this.s2 = 0; // Arrow function setInterval(() => this.s1++, 1000); SetInterval (function () {this.s2++; }, 1000); } var timer = new Timer(); setTimeout(() => console.log('s1: ', timer.s1), 3100); setTimeout(() => console.log('s2: ', timer.s2), 3100); // s1: 3 // s2: 0Copy the code
In the above code, two timers are set inside the Timer function, using the arrow function and the normal function. The former has the scope in which the this binding is defined (the Timer function), and the latter has the scope in which the runtime is defined (the global object). So, after 3100 milliseconds, timer.s1 is updated 3 times, and timer.s2 is not updated once.
The arrow function can make this point immobilized, which is useful for encapsulating callback functions. Here is an example where the DOM event callback function is wrapped in an object.
var handler = { id: '123456', init: function() { document.addEventListener('click', event => this.doSomething(event.type), false); }, doSomething: function(type) { console.log('Handling ' + type + ' for ' + this.id); }};Copy the code
In the init method of the above code, the arrow function is used, which causes this in the arrow function to always point to the handler object. Otherwise, when the callback runs, the this.doSomething line will report an error because this points to the Document object.
This is fixed, not because the arrow function has a mechanism to bind this, but because the arrow function does not have its own this, so the inner this is the outer code block’s this. Because it does not have this, it cannot be used as a constructor.
So, the arrow function into ES5 looks like this.
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
Copy the code
In the code above, the converted VERSION of ES5 makes it clear that the arrow function does not have its own this at all, but instead refers to the outer this.
How many “this” are there in the code below?
function foo() {
return () => {
return () => {
return () => {
console.log('id:', this.id);
};
};
};
}
var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
var t3 = f()().call({id: 4}); // id: 1
Copy the code
In the code above, there is only one this, which is the this of function foo, so t1, T2, t3 all output the same result. Because all the inner functions are arrow functions and don’t have their own this, their this is actually the this of the outermost foo function.
In addition to this, the following three variables also don’t exist in the arrow function, pointing to the corresponding variables of the outer function: arguments, super, and new.target.
function foo() {
setTimeout(() => {
console.log('args:', arguments);
}, 100);
}
foo(2, 4, 6, 8)
// args: [2, 4, 6, 8]
Copy the code
In the above code, the arguments variable inside the arrow function is actually the arguments variable for the function foo.
In addition, since the arrow function does not have its own this, it cannot of course use call(), apply(), or bind() to change the direction of this.
(function() {
return [
(() => this.x).bind({ x: 'inner' })()
];
}).call({ x: 'outer' });
// ['outer']
Copy the code
In the above code, the arrow function does not have its own this, so the bind method is invalid. The inner this points to the outer this.
The JavaScript language’s This object has long been a headache, and using this in object methods must be done with great care. The arrow function “bind” this largely solves this problem.
Not applicable
Since the arrow function causes this to change from “dynamic” to “static”, the arrow function should not be used in the following two situations.
The first case is to define a method of an object that includes this inside.
const cat = { lives: 9, jumps: () => { this.lives--; }}Copy the code
In the code above, the cat.jumps() method is an arrow function, which is incorrect. 4. When calling cat.jumps(), the this inside the method points to cat if it is a normal function. If you write an arrow function like the one above, such that this points to a global object, you will not get the expected result. This is because the object does not constitute a separate scope, resulting in the scope of the jump arrow function being defined as global.
Let’s do another example.
globalThis.s = 21;
const obj = {
s: 42,
m: () => console.log(this.s)
};
obj.m() // 21
Copy the code
In the example above, obj.m() is defined using the arrow function. The JavaScript engine does this by generating the arrow function in the global space and assigning it to obj.m. This causes this inside the arrow function to point to the global object, so obj.m() prints 21 in the global space instead of 42 inside the object. The code above is actually equivalent to the code below.
globalThis.s = 21;
globalThis.m = () => console.log(this.s);
const obj = {
s: 42,
m: globalThis.m
};
obj.m() // 21
Copy the code
For this reason, it is recommended that the attributes of an object be defined in the traditional way rather than using arrow functions.
The second case is when dynamic this is required, and arrow functions should also not be used.
var button = document.getElementById('press');
button.addEventListener('click', () => {
this.classList.toggle('on');
});
Copy the code
When the code above runs, clicking on the button will cause an error because button’s listener is an arrow function, resulting in this being the global object. If changed to a normal function, this dynamically points to the button object being clicked.
Nested arrow functions
Inside the arrow function, you can use the arrow function again. Here is an ES5 syntax for multiple nested functions.
function insert(value) { return {into: function (array) { return {after: function (afterValue) { array.splice(array.indexOf(afterValue) + 1, 0, value); return array; }}; }}; } insert(2).into([1, 3]).after(1); / / [1, 2, 3]Copy the code
So this function up here, you can rewrite it using the arrow function.
let insert = (value) => ({into: (array) => ({after: (afterValue) => { array.splice(array.indexOf(afterValue) + 1, 0, value); return array; }})}); insert(2).into([1, 3]).after(1); / / [1, 2, 3]Copy the code
Most of this article comes from the following ES6 tutorial:
Getting started with ECMAScript 6
ECMAScript 6 profile