1, the preface

  • This is in the process of learning ES6, encountered very easy to ignore the knowledge point!

Did you know that the let in the for loop has a separate scope?

So what is the output

let i = 5;
for (let i = 0; console.log(i), i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
/ / output
/ / 0
// abc
/ / 1
// abc
/ / 2
// abc
/ / 3

Copy the code

Let I = 5; let I = 5; Let I = 0 in the body of the for loop; If these two I’s are in the same scope, we’re going to get an error, which means they’re not in the same scope, and then we’re going to see if the I in the body of the for loop and the I in the body of the for loop are in the same scope, and we’re going to print out that they’re not in the same scope.

Can object deconstruction assignments take inherited properties?

Yes.

const obj1 = {};
const obj2 = { name: 'xiaoming' };
Object.setPrototypeOf(obj1, obj2);

const { name } = obj1;
name // "xiaoming"
Copy the code

Do I need parentheses to assign values to declared variable structures?

// This is not the case
let x;
{x} = {x: 1};
Copy the code

The above code is written incorrectly because the JavaScript engine interprets {x} as a block of code, resulting in a syntax error that requires enclosing the entire structure statement in parentheses.

// The correct way to write
let x;
({x} = {x: 1});
Copy the code

The length attribute of a function is the number of default parameters in the function. If the default parameter has a default value, what can happen?

(function (a) {}).length / / 1
(function (a = 5) {}).length / / 0
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.

(function (a = 0, b, c) {}).length / / 0
(function (a, b = 1, c) {}).length / / 1
Copy 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.

If the parameter is set to a default value, it will affect the result of the currization.

5. You don’t know how to use Array

The array. from method is used to convert two types of objects into real arrays:

  • Array-like object (array-like object)
  • Iterable objects (including new ES6 data structures Set and Map)

The definition says array. from can convert an array-like object to an Array, as follows:

Array.from({ length: 3 });
// [ undefined, undefined, undefined ]
Copy the code

Array.from can also take a second argument, similar to the map method of arrays.

Array.from(arrayLike, x => x * x); From (arrayLike).map(x => x * x); Array.from([1, 2, 3], (x) => x * x)Copy the code

If the map function uses this, it can also pass a third parameter to array. from to bind this.

The includes and indexOf methods are used to determine whether an element exists in an array.

if([1, 2, 3].indexOf(2) ! == -1) {// }Copy the code

The indexOf method has two drawbacks. First, it is not semantic enough. It means to find the first occurrence position of the parameter value, so it is not intuitive enough to compare whether the value is not equal to -1. Second, it uses the strict equality operator (===) internally for judgment, which leads to misjudgment of NaN.

[NaN].indexOf(NaN)
// -1
Copy the code

Includes does not have this problem because it uses a different determination algorithm.

[NaN].includes(NaN)
// true
Copy the code

The join() and toString() methods on arrays that contain undefined or null are treated as empty strings

[1, undefined, 2].join(); // "1, 2,"
[1, undefined, 2].toString()]() // "1, 2,"

[1, null, 2].join(); // "1, 2,"
[1, null, 2].toString()]() // "1, 2,"
Copy the code

Traversal object operations versus enumerability

The enumeration of

Each property of an object has a Descriptor that controls the behavior of the property. The description of the Object. GetOwnPropertyDescriptor method can obtain the attribute Object.

let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
//    value: 123,
//    writable: true,
//    enumerable: true,
//    configurable: true
//  }
Copy the code

An enumerable property that describes an object is called “enumerable.” If it is false, it means that some operations ignore the current property.

Property traversal

ES6 has five methods for traversing an object’s properties.

  • for… in

for… The in loop iterates over the object’s own and inherited enumerable properties (excluding the Symbol property).

  • Object.keys(obj)

Keys returns an array containing the key names of all of the Object’s own (not inherited) enumerable properties (not including the Symbol property).

  • Object.getOwnPropertyNames(obj)

Object. GetOwnPropertyNames returns an array containing all attributes of the Object itself (excluding Symbol attribute, but cannot be enumerated attribute) of keys.

  • Object.getOwnPropertySymbols(obj)

Object. GetOwnPropertySymbols returns an array containing all the Symbol attribute of the Object itself the key name.

  • Reflect.ownKeys(obj)

Reflect.ownKeys returns an array containing all the key names of the object itself, whether they are symbols or strings or enumerable.

All five methods follow the same sequence rules for traversal of attributes

  • First, all numeric keys are iterated, sorted in ascending order.
  • Next, all the string keys are iterated in ascending order by the time they were added.
  • Finally, all Symbol keys are iterated in ascending order of time they were added.
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2'.'10'.'b'.'a', Symbol()]
Copy the code

In the above code, the reflect. ownKeys method returns an array containing all the properties of the argument object. The array’s properties are in this order, starting with the numeric properties 2 and 10, followed by the string properties B and A, and finally the Symbol property.

Can object and array extension operators be followed by expressions?

Yes.

const obj = { ... (x > 1 ? {a: 1} : {}), b: 2, };Copy the code
const arr = [
  ...(x > 0 ? ['a'] : []),
  'b',];Copy the code

Difference between WeakSet and Set?

There are two differences

  • The first point,WeakSetThe members of the object can only be object types, not values of other types.
const ws = new WeakSet(); Ws. The add ({a: 1}) / / ws correctly. The add () [1, 2] / / right wa. Add (1) / / errorsCopy the code
  • Second, objects in a WeakSet are weak references.

Similarly, there are two differences between WeakMap and Map

  • The first point,WeakMapOnly objects (except null) are accepted as key names, and values of other types are not accepted as key names.
  • The second point,WeakMapIs not counted in the garbage collection mechanism

Assigning a value to a property of an object. Normally this value is assigned to an object, but in one case it is assigned to the prototype of that object

Why does the following code print 1

const handler = {
  set: function(obj, prop, value, receiver) {
    console.log(1)
  }
};
const proxy = new Proxy({}, handler);
const myObj = {};
Object.setPrototypeOf(myObj, proxy);

myObj.foo = 'bar';
Copy the code

The reason is that if myObj’s prototype deploys a set method and there is no foo on myObj, then assigning a value to foo on myObj first looks to see if myObj has foo on it. If there is no foo on myObj, it goes back to its prototype to find foo. In this case, the proxy’s set method is triggered, so it prints 1.

If the resolve function in a Promise fails, the error thrown by the Promise object is not passed to the outer code

const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {// The following line is an error because x does not declare resolve(x + 2); }); }; someAsyncThing().then(function() {
  console.log('everything is great');
});

setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123
Copy the code
  • In the code above,someAsyncThingFunction generatedPromiseObject with an internal syntax error. When the browser runs to this line, it will print an errorReferenceError: x is not defined, but does not exit the process, terminate script execution,2It will output again after a second123.
  • That is to say,PromiseInternal errors do not affectPromiseExternal code, as it’s colloquially knownPromises eat up mistakes.

How to control flow management with Generator functions

The code is as follows, how to automatically execute the following generator functions (this process management code is suitable for synchronization tasks, I think it can be called JS responsibility chain mode, very convenient process management)

function* runTask(value1) {
  try {
    var value2 = yield step1(value1);
    var value3 = yield step2(value2);
  } catch (e) {
  
  }
}
Copy the code

The automatic execution code is as follows

scheduler(runTask(initialValue));

functionscheduler(task) { var taskObj = task.next(task.value); // Continue if Generator is not finishedif (!taskObj.done) {
    task.value = taskObj.value
    scheduler(task);
  }
}
Copy the code