
symbol . What for? There are three main reasons for the appearance of this data type.for-in loops and methods like Object.keys . var myObject = {firstName:'raja', lastName:'rao'} Object.keys(myObject) command, it returns the array [firstName, lastName] .myObject object, for example, newProperty . In doing so, we need the Object.keys(myObject) command to return the same values ​​as before (in other words, something should make this function ignore the new property newProperty ), that is, [firstName, lastName] , and not [ firstName, lastName, newProperty] . How to do it?symbol data type, this could not be done. Now, if you add newProperty as a symbol, the Object.keys(myObject) command Object.keys(myObject) ignore this property (since it simply does not know about it) and returns what is needed - [firstName, lastName] .toUpperCase method in Array.prototype .Array.prototype.toUpperCase method. This may well cause your code to stop working correctly. Array.prototype.toUpperCase = function(){ var i; for (i = 0; i<this.length; i++){ this[i] = this[i].toUpperCase(); } return this; } var myArray = ['raja', 'rao']; myArray.toUpperCase(); //['RAJA', 'RAO'] String.prototype.search , to call your own function that implements your logic to search for something in the string. That is, for example, it is necessary that the construction 'somestring'.search(myObject); would call the search function of the myObject object and pass it, as an argument, 'somestring' . How to do it?Symbol . This function will return a value of type symbol . // mySymbol symbol var mySymbol = Symbol(); new , a new object is expected to return, you cannot use the keyword new to create entities of type symbol . var mySymbol = new Symbol(); // , // mySymbol , // - "some text" const mySymbol = Symbol('some text'); const mySymbol1 = Symbol('some text'); const mySymbol2 = Symbol('some text'); mySymbol1 == mySymbol2 // false symbol type variables using the Symbol() function, you can create them using the Symbol.for(<key>) method Symbol.for(<key>) . This method takes a key (string <key> ) and creates new characters. In this case, if this key is given a key already assigned to an existing symbol, it will simply return that existing symbol. Therefore, we can say that the behavior of Symbol.for resembles a singleton design pattern. var mySymbol1 = Symbol.for('some key'); // var mySymbol2 = Symbol.for('some key'); // mySymbol1 == mySymbol2 //true Symbol.for method exists so that you can create characters in one place and work with them in another..for() method .for() transfer of a key that has already been used, it does not create a new character with such a key, but returns an existing one. Therefore, use it with caution.Symbol.for construction, the symbols, even when using the same keys, will be unique. However, if you use Symbol.for , then specifying non-unique keys and symbols returned by Symbols.for will be non-unique. Consider an example. var mySymbol1 = Symbol('some text'); // "some text" var mySymbol2 = Symbol('some text'); // "some text" var mySymbol3 = Symbol.for('some text'); // "some text" var mySymbol4 = Symbol.for('some text'); // , mySymbol3 // true, // .for // mySymbol3 == mySymbol4 //true // mySymbol1 == mySymbol2 //false mySymbol1 == mySymbol3 //false mySymbol1 == mySymbol4 //false const mySymbol = Symbol("Some car description"); const myObject = {name: 'bmw'}; myObject[mySymbol] = 'This is a car'; // // console.log(myObject[mySymbol]); //'This is a car' let myCar = {name: 'BMW'}; let type = Symbol('store car type'); myCar[type] = 'A_1uxury_Sedan'; let honk = Symbol('store honk function'); myCar[honk] = () => 'honk'; // myCar.type; // myCar[type]; // 'store car type' myCar.honk(); // myCar[honk](); // 'honk' for-in loop loops over the properties of the obj object, but it does not know about the prop3 and prop4 (or ignores these properties), since their identifiers are represented by characters. var obj = {}; obj['prop1'] = 1; obj['prop2'] = 2; // -, // ( // ) var prop3 = Symbol('prop3'); var prop4 = Symbol('prop4'); obj[prop3] = 3; obj[prop4] = 4; for(var key in obj){ console.log(key, '=', obj[key]); } // , // prop3 prop4 //prop1 = 1 //prop2 = 2 // prop3 prop4 , // console.log(obj[prop3]); //3 console.log(obj[prop4]); //4 Object.keys and Object.getOwnPropertyNames ignore property names represented by characters. const obj = { name: 'raja' }; // - obj[Symbol('store string')] = 'some string'; obj[Symbol('store func')] = () => console.log('function'); // - // console.log(Object.keys(obj)); //[name] console.log(Object.getOwnPropertyNames(obj)); //[name] Array object by adding our own Array.prototype.includes method to its prototype. This method will conflict with the standard includes method that is present in ES2018 JavaScript. How to equip a prototype with this method and avoid collisions?includes and assign a symbol to it. Then you need to use this variable to add a new property to the global Array object using the bracket notation. After that, it remains only to assign the necessary function to the new property.arr[includes]() , and not a regular string. var includes = Symbol('will store custom includes method'); // Array.prototype Array.prototype[includes] = () => console.log('inside includes func'); // var arr = [1,2,3]; // // includes console.log(arr.includes(1)); //true console.log(arr['includes'](1)); //true // includes arr[includes](); // 'inside includes func', includes - Symbol object (this is the same object that we used to create new characters).String.prototype.search and String.prototype.replace standard objects like String or Array .Symbol.match , Symbol.replace , Symbol.search , Symbol.iterator and Symbol.split .String.prototype.search method of the String.prototype.search object searches the string using a regular expression or a sample string, and if it managed to find what it needs, it returns the index of the search term in the analyzed string. 'rajarao'.search(/rao/); 'rajarao'.search('rao'); Symbol.search method is Symbol.search in a RegExp object. If this is the case, then it is the method of the RegExp object that is being searched for. Thus, the basic objects, like RegExp , implement methods corresponding to Symbol.search , which solve search problems.'rajarao'.search('rao'); command 'rajarao'.search('rao');"rajarao" converted to a String (new String("rajarao")) object String (new String("rajarao"))"rao" character sequence is converted to a RegExp (new Regexp("rao")) object RegExp (new Regexp("rao"))search method of a String object based on the string "rajarao"search method of the "rajarao" object "rajarao" method of the "rao" object is called (that is, the search operation is delegated to the "rao" object). The string "rajarao" passed to this method. If you schematically present this call, it can look something like this: "rao"[Symbol.search]("rajarao")"rao"[Symbol.search]("rajarao") returns, as a search result, the number 4 representing the index of the search substring in the string of the search function of the object "rajarao" , and this function, in turn, returns 4 to our code . // String class String { constructor(value){ this.value = value; } search(obj){ // Symbol.search obj // value obj[Symbol.search](this.value); } } // RegExp class RegExp { constructor(value){ this.value = value; } // [Symbol.search](string){ return string.indexOf(this.value); } } RegExp object. The standard function String.prototype.search can now correctly perceive any object that implements the Symbol.search method, which returns what the developer needs, and this will not break the code. Let us dwell on this in more detail.String.prototype.search the search function of our own class Product . This is possible thanks to the global symbol Symbol.search . class Product { constructor(type){ this.type = type; } // [Symbol.search](string){ return string.indexOf(this.type) >=0 ? 'FOUND' : "NOT_FOUND"; } } var soapObj = new Product('soap'); 'barsoap'.search(soapObj); //FOUND 'shampoo'.search(soapObj); //NOT_FOUND 'barsoap'.search(soapObj); command 'barsoap'.search(soapObj);"barsoap" converted to a String object ( new String("barsoap") )soapObj already an object, it is not converted.search method of a String object based on the string "barsoap"Symbol.search method of the Symbol.search object is soapObj (the search operation is delegated to this object), and the string "barsoap" . In fact, we are talking about this command: soapObj[Symbol.search]("barsoap")
soapObj[Symbol.search]("barsoap")
soapObj[Symbol.search]("barsoap") returns to the search function a result that, in accordance with the internal logic of the soapObj object, can be FOUND and NOT_FOUND . The search function returns this result to our code.for-of loop and an extension operator ( … ), designed to extract data sets from standard objects like arrays, strings, objects of type Map . Why don't we use these standard methods to work with our own objects that store data sets?for-of loop and the extension operator cannot be used to extract data from the User class, which we have created ourselves. Here, to work with it, you have to use the get method, which we also created ourselves. // // for-of // // Users, // class Users { constructor(users){ this.users = users; } // get() { return this.users; } } const allUsers = new Users([ { name: 'raja' }, { name: 'john' }, { name: 'matt' }, ]); // allUsers.get() , for (const user of allUsers){ console.log(user); } // TypeError: allUsers is not iterable // const users = [...allUsers]; // TypeError: allUsers is not iterable iterables .Symbol.iterator symbol, which implements the method described in clauses 3-6.Symbol.iterator method should return another object - an iterator.next method.next method should have access to the data described in clause 1.next method is called, the data from point 1 should be returned, either in the format {value:<stored data>, done: false} , if the iterator can return something else, or in the form {done: true} , if The iterator has nothing more to return.Users object iterable. // // Users , // Symbol.iterator, next, // class Users{ constructor(users){ this.users = users; } // Symbol.iterator - , // [Symbol.iterator](){ let i = 0; let users = this.users; // return { next(){ if (i<users.length) { return { done: false, value: users[i++] }; } return { done: true }; }, }; } } //allUsers const allUsers = new Users([ { name: 'raja' }, { name: 'john' }, { name: 'matt' }, ]); //allUsersIterator const allUsersIterator = allUsers[Symbol.iterator](); // next , // console.log(allUsersIterator.next()); console.log(allUsersIterator.next()); console.log(allUsersIterator.next()); // : //{ done: false, value: { name: 'raja' } } //{ done: false, value: { name: 'john' } } //{ done: false, value: { name: 'matt' } } // for-of for(const u of allUsers){ console.log(u.name); } // : raja, john, matt // console.log([...allUsers]); // allUsers ) for-of , <iterable>[Symbol.iterator]() , ( allUsersIterator ), .*<myGenerator> . - function * myGenerator(){}myGenerator() generator , () , , , iterator .yield .yield , .yield , , next .*getIterator() ) Symbol.iterator next() , . // , // - (*getIterator()) // class Users{ constructor(users) { this.users = users; this.len = users.length; } // , *getIterator(){ for (let i in this.users){ yield this.users[i]; // , //yield } } } const allUsers = new Users([ { name: 'raja' }, { name: 'john' }, { name: 'matt' }, ]); //allUsersIterator const allUsersIterator = allUsers.getIterator(); // next , // console.log(allUsersIterator.next()); console.log(allUsersIterator.next()); console.log(allUsersIterator.next()); console.log(allUsersIterator.next()); // : //{ done: false, value: { name: 'raja' } } //{ done: false, value: { name: 'john' } } //{ done: false, value: { name: 'matt' } } //{ done: true, value: undefined } // for-of for(const u of allUsers.getIterator()){ console.log(u.name); } // : raja, john, matt // console.log([...allUsers.getIterator()]); // * ) yield . // Users - , function* Users(users){ for (let i in users){ yield users[i++]; // , //yield } } const allUsers = Users([ { name: 'raja' }, { name: 'john' }, { name: 'matt' }, ]); // next , // console.log(allUsers.next()); console.log(allUsers.next()); console.log(allUsers.next()); console.log(allUsers.next()); // : //{ done: false, value: { name: 'raja' } } //{ done: false, value: { name: 'john' } } //{ done: false, value: { name: 'matt' } } //{ done: true, value: undefined } const allUsers1 = Users([ { name: 'raja' }, { name: 'john' }, { name: 'matt' }, ]); // for-of for(const u of allUsers1){ console.log(u.name); } // : raja, john, matt const allUsers2 = Users([ { name: 'raja' }, { name: 'john' }, { name: 'matt' }, ]); // console.log([...allUsers2]); // allUsers , , , Generator .Generator throw return , next . , , .yield ( , ) , , , yield .yield , . , generator.next("some new value") , yield .
function* generator(a, b){ // a + b // , k , // a + b let k = yield a + b; // m let m = yield a + b + k; yield a + b + k + m; } var gen = generator(10, 20); // a + b // , done false, // yield console.log(gen.next()); //{value: 30, done: false} // , //a b, .next() , - //, , // // k 50 a + b + k console.log(gen.next(50)); //{value: 80, done: false} // , a, b k. // .next() , // , // m 100 a + b + k + m console.log(gen.next(100)); //{value: 180, done: false} // .next(), undefined, // yield console.log(gen.next()); //{value: undefined, done: true} // // - function *myGenerator() {} // function * myGenerator() {} // function* myGenerator() {} // const myGenerator = function*() {} // , // let generator = *() => {} // //SyntaxError: Unexpected token * // ES2015 class MyClass { *myGenerator() {} } // const myObject = { *myGenerator() {} } yield , return . , , return , . , yield , . function* myGenerator() { let name = 'raja'; yield name; console.log('you can do more stuff after yield'); } // const myIterator = myGenerator(); // .next() console.log(myIterator.next()); //{value: "raja", done: false} // .next() // // 'you can do more stuff after yield' //{value: undefined, done: true} console.log(myIterator.next()); yield , , return , , yield . function* myGenerator() { let name = 'raja'; yield name; let lastName = 'rao'; yield lastName; } // const myIterator = myGenerator(); // .next() console.log(myIterator.next()); //{value: "raja", done: false} // .next() console.log(myIterator.next()); //{value: "rao", done: false} .next() ..next() , ( ). ( 23 ), .next(23) . function* profileGenerator() { // .next() , //, yield, . // , , // .next(), answer let answer = yield 'How old are you?'; // 'adult' 'child' // answer if (answer > 18){ yield 'adult'; } else { yield 'child'; } } // const myIterator = profileGenerator(); console.log(myIterator.next()); //{value: "How old are you?", done: false} console.log(myIterator.next(23)); //{value: "adult", done: false} .next() . , .co .next(result) №5 10, . co(function *() { let post = yield Post.findByID(10); let comments = yield post.getComments(); console.log(post, comments); }).catch(function(err){ console.error(err); }); co , ,Post.findByID(10)Post.findByID(10).next(result)postpost.getComments()post.getComments().next(result)commentsconsole.log(post, comments);co . , — , ECMAScript , . async await .await yield .await .async function , function* .async/await — , « ».async , , JavaScript- , -. , , await . , await , , .getAmount — getUser getBankBalance . , async/await . // ES2015... function getAmount(userId){ getUser(userId) .then(getBankBalance) .then(amount => { console.log(amount); }); } // async/await ES2017 async function getAmount2(userId){ var user = await getUser(userId); var amount = await getBankBalance(user); console.log(amount); } getAmount('1'); //$1,000 getAmount2('1'); //$1,000 function getUser(userId){ return new Promise(resolve => { setTimeout(() => { resolve('john'); }, 1000); }); } function getBankBalance(user){ return new Promise((resolve, reject) => { setTimeout(() => { if (user == 'john'){ resolve('$1,000'); } else { reject('unknown user'); } }, 1000); }); } Symbol.asyncIterator , — for-await-of , ..next() {value: 'some val', done: false}: iterator.next() //{value: 'some val', done: false}.next() , , , {value: 'some val', done: false} . iterator.next().then(({ value, done })=> {//{value: 'some val', done: false}} for-await-of . const promises = [ new Promise(resolve => resolve(1)), new Promise(resolve => resolve(2)), new Promise(resolve => resolve(3)), ]; // , // async function test(){ for await (const p of promises){ console.log(p); } } test(); //1, 2, 3 Object.keys for-in .for-of ..next() . .
Source: https://habr.com/ru/post/359004/
All Articles