1.Symbol
Symbol is a new basic type; The main function is to define unique attribute names. This feature can also be used to protect private variables. Because the outside world cannot generate the same symbol, it cannot be accessed;
If you want to reuse this symbol, you can use the static method symbol for(value: string); The Global Registry will record the correspondence between this string and symbol, so if the incoming value is not a string, it will be converted into a string;
Symbol property cannot be used by for In and object Keys () and so on. Similarly, the symbol attribute value will be ignored during json serialization; But you can use object Getownpropertysymbols() get
obj = {name: 'zs', age:22, [Symbol()]:2}; console.log(Reflect.has(obj, 'name')); // true console.log(Reflect.deleteProperty(obj, 'name')); // true console.log(Reflect.ownKeys(obj)); // [ 'age', Symbol() ] console.log(Object.getOwnPropertySymbols(obj)); // [ Symbol() ]
2.for...of...
for # of # is a unified way to traverse all data structures # requires data to implement an iterative interface # iterable interface
For # of # can use break to terminate the loop # for # of can traverse all iteratable objects # or even pseudo array # Set # Map
Traversing the map obtains an array. Array 0 is the key and 1 is the value of # for (const [key, value] of # map)
arr.forEach() / / the loop cannot be terminated
arr.some(); return true: terminate
arr.every(); return: false: terminate
const arr = [1,2,3,4,2,2,44]; for (const item of arr) { console.log(item); if (item >= 4) break; } // You can jump out of the loop through break
Why does const be used to define for of while const is used to report an error?
Because for # in # and for # of # will create a separate block level scope for each cycle, const is used to ensure that the value will not be modified, while ordinary for will only create a block level scope;
3.iterator
The Iterable interface needs to be implemented when using for of to traverse the data structure
By printing iteratable data structures such as array _ set map, it is found that they are in the proto type object (__) Both:
Symbol(Symbol.iterator): ƒ values() arguments: (...) caller: (...) length: 0 name: "values" __proto__: ƒ () [[Scopes]]: Scopes[0]
When you call this method, you can see a next method:
Array Iterator {} __proto__: Array Iterator next: ƒ next() arguments: (...) caller: (...) length: 0 name: "next" __proto__: ƒ () [[Scopes]]: Scopes[0] Symbol(Symbol.toStringTag): "Array Iterator" __proto__: Object
View, obtain and execute next through the set structure:
const set = new Set(); set.add("22").add("33").add("wa"); const iterator = set[Symbol.iterator](); console.log(iterator.next()); // { value: '22', done: false } console.log(iterator.next()); // { value: '33', done: false } console.log(iterator.next()); // { value: 'wa', done: false } console.log(iterator.next()); // { value: undefined, done: true } console.log(iterator.next()); // { value: undefined, done: true }
Simulate this iterator manually:
const obj = { arr: ['qqq','www','eee'], [Symbol.iterator]: function() { let index = 0; const self = this; console.log(this); /** * {arr: [ 'qqq', 'www', 'eee' ], [Symbol(Symbol.iterator)]: [Function: [Symbol.iterator]]} */ return { next() { const result = { value: self.arr[index], done: index >= self.arr.length, } index ++; return result; } } } } for (const item of obj) { console.log(item); // qqq // www // eee }
4.generator generator
ES2015 appears mainly to solve the problem of asynchronous nesting; But there are disadvantages: it is necessary to define an additional executor method and call methods such as next () to execute the generator object;
function * a() { let index = 0; console.log(index); // 0 const obj1 = yield index++; console.log(obj1); // undefined const obj2 = yield index++; console.log(obj2); // 1 const obj3 = yield index++; console.log(obj3); const obj4 = yield index++; console.log(obj4); return 'return 1'; } const g = a(); console.log(g); // Object [Generator] {} let value = g.next(); console.log(value,333); // { value: 0, done: false } value = g.next(); console.log(value,334); // { value: 1, done: false } value = g.next(value.value); console.log(value); // { value: 2, done: false }
Using the generator, you can define iteratable attributes more easily:
// Iterators can be implemented through generators const obj = { arr: ['qqq','www','eee'], [Symbol.iterator]: function * () { const all = [...this.arr,] for (const item of all) { // for of is used here because the array implements the iterator by default. You can also use other methods to iterate yield item; } } } for (const item of obj) { console.log(item); // qqq // www // eee } // Return the iterator to a generator function. When accessed externally through for of, for of will call the next method of the iterator, so that the object can be iterated
5.getter setter
getter ES2015 get property () {return ...} No parameters allowed
set prop(val) { . . . } one parameter
After ES2015, you can use get [express] () {} to define getter s and setter s for calculating property names
The created attribute is a pseudo attribute, and its assignment will not affect it
You can delete using delete
You can use defineProperty to define an existing object;
The delay calculation can only be calculated when necessary. When defining, the performance can be optimized with the help of cache;
When the get keyword is used, it is similar to object Defineproperty () has a similar effect, with slight differences when used in classes.
When using the get keyword, the attribute will be defined on the prototype of the instance. When using object When defineproperty(), the property will be defined on the instance itself.
Object. The values of object.03 and 22.04 assign cannot be copied
If you want to copy getter s and setter s, you can use getOwnPropertyDescriptor to get the descriptor information of the specified property, and then add the descriptor through defineProperty
class Example { get hello() { return 'world'; } } const obj3 = new Example(); console.log(obj3.hello); // "world" console.log(Object.getOwnPropertyDescriptor(obj3, 'hello')); // undefined console.log( Object.getOwnPropertyDescriptor( Object.getPrototypeOf(obj3), 'hello' ) ); // { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }
6. New features of es2016
arr.includes() determines whether the array has the specified value, and returns boolean() to determine whether the two NaN are equal
arr.indexOf() returns that if the index cannot be found, it returns - 1 to judge that the two NaN are not equal
Exponential operator * * 2 * * 10 = = = 1024
7. New features of es2017
Object.values(obj) returns the Array of all values of the object
Object.entries(obj) returns the Array of all key value pairs of the object. The key value is also Array
You can use entries with for of to implement traversal instead of implementing the iterable interface
for (const [key, value] of Object.entries(obj)) { console.log(key, value); }
Object. The getownpropertydescriptors () method is used to obtain the descriptors of all its own properties of an object
Object.getOwnPropertyDescriptor(obj1,'all') method returns the descriptor of the property of the object;
Async / wait , is simpler than the generator, and the synchronous writing method is easier to read , which is actually a Promise syntax sugar; A common value in return is that , will wrap it as Promise , similar to Promise Resolve() static method; (Promise source code learning notes needtodo)