1. What is the difference between es5 and es6【es9】?
(1) Var will have variable promotion phenomenon, but let and const will not have this situation
(2) Temporary dead zone referred to as TDZ : As long as there is a let
command in the block-level scope, the variable declared by it is "bound" ( binding) This area is no longer affected by external influences.
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
ES6 clear that, if the block exists let
and const
command, this block these commands variable declarations, from the outset to form a closed scope. If these variables are used before the declaration, an error will be reported.
The essence of the temporary dead zone is that as soon as it enters the current scope, the variable to be used already exists, but it is not available. Only when the line of code that declares the variable appears, can the variable be obtained and used.
Why is block scope needed?
ES5 has only global scope and function scope, and no block-level scope, which brings many unreasonable scenarios.
In the first scenario, inner variables may cover outer variables.
In the second scenario, the loop variable used for counting is leaked as a global variable.
ES6's block-level scope
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
ES6 allows arbitrary nesting of block-level scope. The emergence of block-level scope actually makes the widely used immediate execution function expression (IIFE) unnecessary.
What is the difference between let and var?
(1) Let is a new command in ES6, used to declare local variables. The usage is similar to var, but the declared variables are only valid in the code content where the let command is located, and there is a temporary dead zone constraint (the previous assignment reports an error, No error is reported after assignment);
(2) Let is not allowed to declare the same variable repeatedly in the same scope;
(3) The var declaration is a global variable outside the method, and the declaration is a local variable inside the method;
(4) Remember the important One point : Variables declared by var will be mounted on the window, while variables declared by let and const will not;
Two, const declares a read-only constant
const
Except for the following two let
differences, other characteristics are the let
same:
1. Once const declares a variable, it must be initialized immediately and cannot be left for later assignment.
2. Once declared, the value of the constant cannot be changed.
Essence : const defines assignment behavior.
const a = 1;
a = 2;//报错
const arr = [];
arr.push(1) //[1]
//在声明引用型数据为常量时,const保存的是变量的指针,只要保证指针不变就不会保存。下面的行为就会报错
arr = [];//报错 因为是赋值行为。变量arr保存的指针改变了。
Three, deconstruction assignment
ES6 allows extracting values from arrays and objects and assigning values to variables according to certain patterns. This is called Destructuring.
1. es5 declares multiple variables at once:
var a = 1,
b = 2,
c = 3,
...;
2. es6 declares multiple variables at once
let [a,b,c] = [1,2,3];
//a = 1
//b = 2
//c = 3
Essentially, this type of writing belongs to "pattern matching". As long as the patterns on both sides of the equal sign are the same, the variable on the left will be assigned the corresponding value.
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
3. If the deconstruction is not successful, the value of the variable is equal to undefined
.
4. The other case is incomplete deconstruction, that is, the pattern on the left side of the equal sign only matches a part of the array on the right side of the equal sign. In this case, deconstruction can still be successful.
5. If the right side of the equal sign is not an array, an error will be reported.
6. Destructuring assignment allows specifying default values.
let [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
7. Note that ES6 uses the strict equality operator ( ===
) internally to determine whether a position has a value. Therefore, if an array member is not strictly equal undefined
, the default value will not take effect.
8. If the default value is an expression, then this expression is evaluated lazily, that is, it will be evaluated only when it is used.
9. The default value can refer to other variables assigned by destructuring, but the variable must have been declared.
Object destructuring assignment
Destructuring can be used not only for arrays, but also for objects:
let {
foo, bar } = {
foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
(1) There is an important difference between object deconstruction and arrays. The elements of the array are arranged in order, and the value of the variable is determined by its position; and the properties of the object have no order, and the variable must have the same name as the property to get the correct value.
let {
bar, foo } = {
foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
let {baz} = {foo: “aaa”, bar: “bbb” };
baz // undefined
(2) If the variable name is inconsistent with the property name, it must be written as follows.
let {
foo: baz } = {
foo: 'aaa', bar: 'bbb' };
baz // "aaa"
let obj = {
first: 'hello', last: 'world' };
let {
first: f, last: l } = obj;
f // 'hello'
l // 'world'
String destructuring assignment
const [a, b, c, d, e] = 'hello';
Objects like arrays have a length
property, so this property can also be deconstructed and assigned.
let {
length : len} = 'hello';
len // 5
Destructuring assignment of function parameters
function add([a,b]){
return a+b;
}
add([2,3])//5
The destructuring of function parameters can also use default values.
function move({
x = 0, y = 0} = {
}) {
return [x, y];
}
move({
x: 3, y: 8}); // [3, 8]
move({
x: 3}); // [3, 0]
move({
}); // [0, 0]
move(); // [0, 0]
use
- In addition to defining multiple variables at once
- You can also make the function return multiple values
- You can easily associate the parameters of the function with the value
- Extract json data
- Default value of function parameters
If var x = 3
the var
removal of the function foo
of internal variables x
to point to the first argument x
, and inside the anonymous function x
is the same, so the final output is 2
the outer layer of the global variable x
remains unaffected.
var x = 1;
function foo(x, y = function() {
x = 2; }) {
x = 3;
y();
console.log(x);
}
foo() // 2
x //
1
Four, rest parameters
ES6 introduces the rest parameter (in the form of...variable name), which is used to obtain the redundant parameters of the function, so that there is no need to use the arguments object. The traversal of the rest parameter is an array, and the variable puts the redundant parameters into the array.
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
arguments
The object is not an array, but an array-like object. So in order to use the array method, you must Array.prototype.slice.call
first convert it to an array. The rest parameter does not have this problem, it is a real array, and all the methods specific to the array can be used. The following is an example of using the rest parameter to rewrite the array push
method.
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
console.log(item);
});
}
var a = [];
push(a, 1, 2, 3)
Note that there can be no other parameters after the rest parameter (that is, it can only be the last parameter), otherwise an error will be reported.
// 报错
function f(a, ...b, c) {
// ...
}
The length
properties of the function , excluding the rest parameter.
(function(a) {
}).length // 1
(function(...a) {
}).length // 0
(function(a, ...b) {
}).length // 1
Five, strict mode
Starting from ES5, the function can be set to strict mode.
ES2016 has made a little modification to stipulate that as long as the function parameters use default values, destructuring assignments, or spread operators, the function cannot be explicitly set to strict mode, otherwise an error will be reported
Six, arrow function
ES6 allows the use of "arrows" ( =>
) to define functions.
If the arrow function does not require parameters or requires multiple parameters, use a parenthesis to represent the parameter part.
var f = () => 5;
// 等同于
var f = function () {
return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
If there is more than one statement in the code block of the arrow function, use braces to enclose them and use the return
statement to return.
var sum = (num1, num2) => {
return num1 + num2; }
Because braces are interpreted as code blocks, if the arrow function returns an object directly, you must add parentheses outside the object, otherwise an error will be reported.
// 报错
let getTempItem = id => {
id: id, name: "Temp" };
// 不报错
let getTempItem = id => ({
id: id, name: "Temp" });
There are several points to note when using arrow functions:
- The
this
object in the function body is the object where it is defined, not the object where it is used. - It cannot be used as a constructor, that is, you cannot use
new
commands, otherwise an error will be thrown. arguments
The object cannot be used , the object does not exist in the function body. If you want to use it, you can use the rest parameter instead.- Not use
yield
command, and therefore can not function as an arrow Generator function.
this
The fixation of the pointing is not because the arrow function has a binding this
mechanism inside . The actual reason is that the arrow function does not have its own at all this
, and the inner this
code is the outer code block this
. Just because it does not have it this
, it cannot be used as a constructor.
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
//转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的this,而是引用外层的this。
//由于箭头函数没有自己的`this`,所以当然也就不能用`call()`、`apply()`、`bind()`这些方法去改变`this`的指向。
Seven, string expansion (includes(), startWith(), endsWith())
Traditionally, JavaScript has only indexOf
methods that can be used to determine whether a string is contained in another string. ES6 provides three new methods.
- includes() : returns a Boolean value, indicating whether the parameter string is found.
- startsWith() : returns a Boolean value, indicating whether the parameter string is at the head of the original string.
- endsWith() : returns a Boolean value, indicating whether the parameter string is at the end of the original string.
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
Note: These three methods all support the second parameter
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
The above code indicates that when using the second parameter n
, endsWith
the behavior is different from the other two methods. It targets the first n
character, while the other two methods target from the n
first position until the end of the string.
The repeat method returns a new string, which means repeating the original string n times
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
- If the parameter is a decimal, it will be rounded down.
- If
repeat
the parameter is negative orInfinity
, an error will be reported. - The parameter is
NaN
equal to 0. - If
repeat
the parameter is a string, it will first be converted to a number.
padStart () 、 padEnd ()
ES2017 introduced the function of string completion length. If a string is not enough for the specified length, it will be completed at the head or tail. padStart()
Used for head completion and padEnd()
tail completion.
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
Template string ``
The string template output of es5 is usually + splicing.
Such shortcomings are obviously easy to see: when there are many string splicing content, it is too confusing and error-prone.
ES6 introduced template strings to solve this problem.
var name = "风屿",trait = "帅气";
//es5
var str = "他叫"+name+",人非常"+trait+",说话又好听";
//es6
var str2 = `他叫 ${
name} ,人非常 ${
trait} ,说话又好听`;
The template string is an enhanced version of the string, which is identified by backticks (`). It can be used as an ordinary string, can also be used to define a multi-line string, or embed variables in the string.
- If you need to use backticks in the template string, use a backslash to escape it.
- If you use a template string to represent a multi-line string, all spaces and indentation will be preserved in the output.
- Variables are embedded in the template string and the variable name needs to be written in it
${}
. - Any JavaScript expression can be placed inside the braces, operations can be performed, and object properties can be referenced.
- Functions can also be called in the template string.
- If the value in the braces is not a string, it will be converted to a string according to general rules. For example, if there is an object in braces, the
toString
method of the object will be called by default . - If the variable in the template string is not declared, an error will be reported.
Label template
The template string can immediately follow a function name, and the function will be called to process the template string. This is called the "label template" function.
alert`123`
// 等同于
alert(123)
If there are variables in the template characters, it is not a simple call, but the template string will be processed into multiple parameters before calling the function.
let a = 5;
let b = 10;
tag`Hello ${
a + b } world ${
a * b }`;
// 等同于
tag(['Hello ', ' world ', ''], 15, 50);