Dylan  Iqbal

Dylan Iqbal

1567216540

A Practical Guide to ES6 Symbols

Originally published by Valeri Karpov at http://thecodebarbarian.com

JavaScript introduced symbols in ES6 as a way to prevent property name collisions. As an added bonus, symbols also provide a way to simulate private properties in 2015-2019 JavaScript.

Introduction

The simplest way to create a symbol in JavaScript is to call the Symbol() function. The 2 key properties that makes symbols so special are:

  1. Symbols can be used as object keys. Only strings and symbols can be used as object keys.
  2. No two symbols are ever equal.
const symbol1 = Symbol();
const symbol2 = Symbol();

symbol1 === symbol2; // false

const obj = {};
obj[symbol1] = ‘Hello’;
obj[symbol2] = ‘World’;

obj[symbol1]; // ‘Hello’
obj[symbol2]; // ‘World’

Although the Symbol() call makes it look like symbols are objects, symbols are actually a primitive type in JavaScript. Using Symbol as a constructor with new throws an error.

const symbol1 = Symbol();

typeof symbol1; // ‘symbol’
symbol1 instanceof Object; // false

// Throws “TypeError: Symbol is not a constructor”
new Symbol();

Descriptions

The Symbol() function takes a single parameter, the string description. The symbol’s description is only for debugging purposes - the description shows up in the symbol’s toString(). However, two symbols with the same description are not equal.

const symbol1 = Symbol(‘my symbol’);
const symbol2 = Symbol(‘my symbol’);

symbol1 === symbol2; // false
console.log(symbol1); // ‘Symbol(my symbol)’

There is also a global symbol registry. Creating a symbol using Symbol.for() adds a symbol to a global registry, keyed by the symbol’s description. In other words, if you create two symbols with the same description using Symbol.for(), the two symbols will be equal.

const symbol1 = Symbol.for(‘test’);
const symbol2 = Symbol.for(‘test’);

symbol1 === symbol2; // true
console.log(symbol1); // ‘Symbol(test)’

Generally speaking, you shouldn’t use the global symbol registry unless you have a very good reason to, because you might run into naming collisions.

Name Collisions

The first built-in symbol in JavaScript was the Symbol.iterator symbol in ES6. An object that has a Symbol.iterator function is considered an iterable. That means you can use that object as the right hand side of a for/of loop.

const fibonacci = {
 [Symbol.iterator]: function*() {
   let a = 1;
   let b = 1;
   let temp;

   yield b;

   while (true) {
     temp = a;
     a = a + b;
     b = temp;
     yield b;
   }
 }
};

// Prints every Fibonacci number less than 100
for (const x of fibonacci) {
 if (x >= 100) {
   break;
 }
 console.log(x);
}

Why is Symbol.iterator a symbol rather than a string? Suppose instead of using Symbol.iterator, the iterable spec checked for the presence of a string property ‘iterator’. Furthermore, suppose you had the below class that was meant to be an iterable.

class MyClass {
 constructor(obj) {
   Object.assign(this, obj);
 }

 iterator() {
   const keys = Object.keys(this);
   let i = 0;
   return (function*() {
     if (i >= keys.length) {
       return;
     }
     yield keys[i++];
   })();
 }
}

Instances of MyClass will be iterables that allow you to iterate over the object’s keys. But the above class also has a potential flaw. Suppose a malicious user were to pass an object with an iterator property to MyClass.

const obj = new MyClass({ iterator: ‘not a function’ });

If you were to use for/of with obj, JavaScript would throw TypeError: obj is not iterable. That’s because the user-specified iterator function would overwrite the class’ iterator property. This is a similar security issue to prototype pollution, where naively copying user data may cause issues with special properties like proto and constructor.

The key pattern here is that symbols enable a clear separation between user data and program data in objects. Since symbols cannot be represented in JSON, there’s no risk of data passed into an Express API having a bad Symbol.iterator property. In objects that mix user data with built-in functions and methods, like Mongoose models, you can use symbols to ensure that user data doesn’t conflict with your built-in functionality.

Private Properties

Since no two symbols are ever equal, symbols are a convenient way to simulate private properties in JavaScript. Symbols don’t show up in Object.keys(), and therefore, unless you explicitly export a symbol, no other code can access that property unless you explicitly go through the Object.getOwnPropertySymbols() function.

function getObj() {
 const symbol = Symbol(‘test’);
 const obj = {};
 obj[symbol] = ‘test’;
 return obj;
}

const obj = getObj();

Object.keys(obj); // []

// Unless you explicitly have a reference to the symbol, you can’t access the
// symbol property.
obj[Symbol(‘test’)]; // undefined

// You can still get a reference to the symbol using getOwnPropertySymbols()
const [symbol] = Object.getOwnPropertySymbols(obj);
obj[symbol]; // ‘test’

Symbols are also convenient for private properties because they do not show up in JSON.stringify() output. Specifically, JSON.stringify() silently ignores symbol keys and values.

const symbol = Symbol(‘test’);
const obj = { [symbol]: ‘test’, test: symbol };

JSON.stringify(obj); // “{}”

Moving On

Symbols are a great tool for representing internal state in objects while ensuring that user data stays separate from program state. With symbols, there’s no more need for conventions like prefixing program state properties with ‘$’. So next time you find yourself setting an object property to $$__internalFoo, consider using a symbol instead.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

The Complete JavaScript Course 2019: Build Real Projects!

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

ES6 Arrow Functions Cheatsheet

Getting Started with ES6 Arrow Functions in JavaScript

The Complete Guide to ES6 Destructuring

Dropbox API / JavaScript ES6 Tutorial - Expense Organizer

Authenticate a Node ES6 API with JSON Web Tokens


#javascript #es6 #web-development

What is GEEK

Buddha Community

A Practical Guide to ES6 Symbols
Dylan  Iqbal

Dylan Iqbal

1567216540

A Practical Guide to ES6 Symbols

Originally published by Valeri Karpov at http://thecodebarbarian.com

JavaScript introduced symbols in ES6 as a way to prevent property name collisions. As an added bonus, symbols also provide a way to simulate private properties in 2015-2019 JavaScript.

Introduction

The simplest way to create a symbol in JavaScript is to call the Symbol() function. The 2 key properties that makes symbols so special are:

  1. Symbols can be used as object keys. Only strings and symbols can be used as object keys.
  2. No two symbols are ever equal.
const symbol1 = Symbol();
const symbol2 = Symbol();

symbol1 === symbol2; // false

const obj = {};
obj[symbol1] = ‘Hello’;
obj[symbol2] = ‘World’;

obj[symbol1]; // ‘Hello’
obj[symbol2]; // ‘World’

Although the Symbol() call makes it look like symbols are objects, symbols are actually a primitive type in JavaScript. Using Symbol as a constructor with new throws an error.

const symbol1 = Symbol();

typeof symbol1; // ‘symbol’
symbol1 instanceof Object; // false

// Throws “TypeError: Symbol is not a constructor”
new Symbol();

Descriptions

The Symbol() function takes a single parameter, the string description. The symbol’s description is only for debugging purposes - the description shows up in the symbol’s toString(). However, two symbols with the same description are not equal.

const symbol1 = Symbol(‘my symbol’);
const symbol2 = Symbol(‘my symbol’);

symbol1 === symbol2; // false
console.log(symbol1); // ‘Symbol(my symbol)’

There is also a global symbol registry. Creating a symbol using Symbol.for() adds a symbol to a global registry, keyed by the symbol’s description. In other words, if you create two symbols with the same description using Symbol.for(), the two symbols will be equal.

const symbol1 = Symbol.for(‘test’);
const symbol2 = Symbol.for(‘test’);

symbol1 === symbol2; // true
console.log(symbol1); // ‘Symbol(test)’

Generally speaking, you shouldn’t use the global symbol registry unless you have a very good reason to, because you might run into naming collisions.

Name Collisions

The first built-in symbol in JavaScript was the Symbol.iterator symbol in ES6. An object that has a Symbol.iterator function is considered an iterable. That means you can use that object as the right hand side of a for/of loop.

const fibonacci = {
 [Symbol.iterator]: function*() {
   let a = 1;
   let b = 1;
   let temp;

   yield b;

   while (true) {
     temp = a;
     a = a + b;
     b = temp;
     yield b;
   }
 }
};

// Prints every Fibonacci number less than 100
for (const x of fibonacci) {
 if (x >= 100) {
   break;
 }
 console.log(x);
}

Why is Symbol.iterator a symbol rather than a string? Suppose instead of using Symbol.iterator, the iterable spec checked for the presence of a string property ‘iterator’. Furthermore, suppose you had the below class that was meant to be an iterable.

class MyClass {
 constructor(obj) {
   Object.assign(this, obj);
 }

 iterator() {
   const keys = Object.keys(this);
   let i = 0;
   return (function*() {
     if (i >= keys.length) {
       return;
     }
     yield keys[i++];
   })();
 }
}

Instances of MyClass will be iterables that allow you to iterate over the object’s keys. But the above class also has a potential flaw. Suppose a malicious user were to pass an object with an iterator property to MyClass.

const obj = new MyClass({ iterator: ‘not a function’ });

If you were to use for/of with obj, JavaScript would throw TypeError: obj is not iterable. That’s because the user-specified iterator function would overwrite the class’ iterator property. This is a similar security issue to prototype pollution, where naively copying user data may cause issues with special properties like proto and constructor.

The key pattern here is that symbols enable a clear separation between user data and program data in objects. Since symbols cannot be represented in JSON, there’s no risk of data passed into an Express API having a bad Symbol.iterator property. In objects that mix user data with built-in functions and methods, like Mongoose models, you can use symbols to ensure that user data doesn’t conflict with your built-in functionality.

Private Properties

Since no two symbols are ever equal, symbols are a convenient way to simulate private properties in JavaScript. Symbols don’t show up in Object.keys(), and therefore, unless you explicitly export a symbol, no other code can access that property unless you explicitly go through the Object.getOwnPropertySymbols() function.

function getObj() {
 const symbol = Symbol(‘test’);
 const obj = {};
 obj[symbol] = ‘test’;
 return obj;
}

const obj = getObj();

Object.keys(obj); // []

// Unless you explicitly have a reference to the symbol, you can’t access the
// symbol property.
obj[Symbol(‘test’)]; // undefined

// You can still get a reference to the symbol using getOwnPropertySymbols()
const [symbol] = Object.getOwnPropertySymbols(obj);
obj[symbol]; // ‘test’

Symbols are also convenient for private properties because they do not show up in JSON.stringify() output. Specifically, JSON.stringify() silently ignores symbol keys and values.

const symbol = Symbol(‘test’);
const obj = { [symbol]: ‘test’, test: symbol };

JSON.stringify(obj); // “{}”

Moving On

Symbols are a great tool for representing internal state in objects while ensuring that user data stays separate from program state. With symbols, there’s no more need for conventions like prefixing program state properties with ‘$’. So next time you find yourself setting an object property to $$__internalFoo, consider using a symbol instead.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

The Complete JavaScript Course 2019: Build Real Projects!

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

ES6 Arrow Functions Cheatsheet

Getting Started with ES6 Arrow Functions in JavaScript

The Complete Guide to ES6 Destructuring

Dropbox API / JavaScript ES6 Tutorial - Expense Organizer

Authenticate a Node ES6 API with JSON Web Tokens


#javascript #es6 #web-development

Condo Mark

Condo Mark

1589611500

The Complete Guide to Symbols in JavaScript

Symbols, the newest JavaScript primitive, bring a few benefits to the language and are particularly useful when used as object properties. But, what can they do for us that strings cannot?

Before we explore symbols too much let’s first look at some JavaScript features which many developers might not be aware of.

#javascript #symbols in javascript #es6

Dylan North

Dylan North

1567668337

Quick Practical Guide for ES6

The list of new functionality is quite big, but here we’ll be focusing on some frequently used ones. We will also explore how to use best practices in our routine development tasks.

ES9 is in the discussion but ES6 is still not completely supported by all browsers. You can check the detailed compatibility table here for reference. ECMAScript(ES) is the standard, while JavaScript is the most popular language that is used to implement this standard and builds on top of it.

Scoping

ES6 introduces some welcome changes to solve common pain points with JavaScript scoping.

Let’s take an example (ES5)

function myFunction() {
 var myValue = "I am value";
 if (1) {
   let myValue = "I am another value";
   console.log(myValue)
 }
 console.log(myValue)
}

Output:

I am another value

I am another value

However, I do not want my outer console.log statement (as in above example) to print the value of the inner variable. This is generally not the desired behaviour.

If we talk about scopes in ES5, there are two scopes in ES5: global and function.

Scope: It’s just a boundary, inside which the variable lives or can be used.

For example:

function myFunction(){
    var myValue = "Don't touch, I'm a value"
}
console.log(myValue)

Output:

ReferenceError: myValue is not defined.

And this is because we’re trying to access the value of variable myValue out of its scope.

Though in ES5 you could achieve it by using IIFE that isn’t such easy.

So, in ES6 a keyword LET is introduced which has a local scope (yes there is another in the next section).

Let is not a replacement of var, but it is said to be a good programming standard in ES6 and typescript because it makes variables scopes predictable and easier to reason about.

Typescript: ES6 standard standard language, extension is, .ts

Let’s see how it resolves the earlier issue(s) (ES6).

function myFunction() {
 var myValue = "I am value";
 if (1) {
   let myValue = "I am another value";
   console.log(myValue)
 }
 console.log(myValue)
}

Output:

I am another value

I am value

You should feel accomplished!! Now try a loop using let for yourself.

Another exciting addition is const, const provides the mechanism of immutability which means, the variables do not change over time.

For example:

const myConst = "my const value";
myConst = "my another const value";

Output:
VM47:1 Uncaught SyntaxError: Identifier ‘myConst’ has already been declared
at <anonymous>:1:1

Before any argument, I would add that, the variable is immutable but not the value it is assigned to. It means if we declare an object as const, we can change the properties of that object.

For Example:

const myConstObject = {};
myConstObject.constProp = “Const Value”;
console.log(myConstObject)

Output:
{constProp: “Const Value”}

Looping

If you are frequently using for…in & foreach loops you may be skeptical of the introduction of for…of but believe me, you’re going to like it!.

So, why for…of arrived, definitely for…of got something better than for…in, let’s check it.

For…in (ES5):

var myCoins = [1,2,5,10];
for( let coin in myCoins){
console.log(typeof(coin));
}

Output:
string
string
string
string

Yes, you read the output right. for…in loop returns a number array as string values. This can obviously confuse and create hard-to-track bugs.

For & ForEach (ES5):

Let’s see a basic example to show how forEach works:

var myCoins = [1,2,5,10,20]
myCoins.forEach(function(value){
console.log(value);
});

Output:
1,2,5,10,20

Yes, that’s right, there is no number to string conversion issues. But there is a problem.

You cannot break out of the loop using break statement and move to the next iteration with continue statement.

For…of:

Introduced in ES6, for…of avoids the issues of the for…in loop, and it works with break and continue statements and even allows return from the enclosing block.

var myCoins = [1,2,5,10];
for( let coin of myCoins){
console.log(typeof(coin));
}

Output:
number
number
number
number

Data Structures

Let’s start with some frequently used ones, like Set and Map.

Set: Let’s quickly cover some of the important bullet points about set.

  • You do not store key-value pair like objects in Set, just the keys.
  • No repeating values, contains distinct elements/objects.
  • Example:
let myCoinSet = new Set();
myCoinSet.add(‘foo’);
myCointSet.size
// 1

myCoinSet.add(‘foo’);
myCoinSet.size
//1

  • Set receives iterable parameter as its input.
  • Example:
let myCoinSet = new Set([1, 2, 3]) - correct
let myCoinSet = new Set(1,2,3) -wrong

Or you can do like:

Let myCoinSet = new Set();
myCoinset.add(1) -correct
myCoinSet.add(1,2,4) -wrong
myCoinSet.add([1,4,5]) -wrong
  • Set does not support random order access of elements like arrays do
  • For Example:
console.log(myCoinSet[1]) -wrong
  • Some common operations of Set:
  • Remove element: myCoinSet.delete(2).
  • Empty the set: myCoinSet.clear();
  • Looping over Set is quite straightforward
  • For Example:
let myCoinSet = new Set([1, 2, 5, 10])		
for (let coin in myCoinSet){
console.log(coin)
}

Output:
1, 2, 5, 10

Map: Let’s quickly cover some of the important bullet points about the map.

  • A map is a key-value pair.
  • An order is maintained as they are saved so when we put loop, it prints in the same order.

Let’s do some fundamental operations using Map.

  • Creating Map:
let myMap = new Map();

Adding pairs

let myMap = new Map();
myMap.set(“Name”, “Carlos”)
myMap.set(“Occupation”, “Engineer” )

Another way of adding:

let myMap = new Map([
[ “Name”, “Alex” ],
[ “Occupation”, “Test Engineer” ],
[ “Company”, “Modus Create” ]
]);

Get element by key

map.get(“Name”)
// Carlos
  • Checking whether key exists
map.has(“Name”)
//true
  • Deleting by key
map.delete(“Name”)
  • Checking size
map.size()
  • Empty whole map
map.clear()
  • Looping over map is quite easy like we did for set, but here we have key-value so, it depends what you want to loop through.
  • Example:
let m = new Map([
[“Name”, “Chris”],
[“Occupation”, “Technical Manager”],
[“Company”, “Modus Create”],
[“Country”, “USA”]
]);

1- for(let keys of m.keys()){
console.log(keys)
}

  • Output:
  • Name, Occupation, Company, Country
2-	for(let value of m.values()){
console.log(values)
}
  • Output:
  • Chris, Technical Manager, Modus Create, USA
3-	 for(let [value, key] of m){
console.log(value: ${value} Key: ${key})
}
  • Output:
value: Name Key: Chris
value: Occupation Key: Technical Manager
value: Company Key: Modus Create
value: Country Key: USA

Let’s discuss How Objects are different from Map

  • In Objects you are bound to use simple keys as string, numbers or symbols but in Map you can use even array and objects.
  • Map is an instance of Object not vice-versa.
  • Functions as values is not possible in Map but in object it’s possible.
  • Example:
var person = {
name: “Carlos”,
workingDays() {
console.log(“25 days average”)
}
}
  • Using objects is preferred over map if your application has bountiful JSON operations.
  • What is your experience using Objects and Maps? Please share your scenarios where you find one of them is more efficient over another. What problem could you not solve by one but not with the other?

There are many more cool and advanced features in ES6 such as Fat arrow function, Destructuring, Modules, Classes, Interfaces, Promises and Types. This is not the end of this topic. Look for the part 2 of this subject in an upcoming post.

Originally published by Nikhil Kumar  at  moduscreate.com

===========================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

How to enable ES6 (and beyond) syntax with Node and Express

Getting Started with ES6 Arrow Functions in JavaScript

JavaScript Try Catch & ⚠ Error Handling ES6 Tutorial (2019)

Understanding Generators in ES6 Javascript


#javascript #es6 #web-development

Joel Kelly

Joel Kelly

1567135740

A Practical Guide to Symbols in JavaScript

JavaScript introduced symbols in ES6 as a way to prevent property name collisions. As an added bonus, symbols also provide a way to simulate private properties in 2015-2019 JavaScript.

Introduction

The simplest way to create a symbol in JavaScript is to call the Symbol() function. The 2 key properties that makes symbols so special are:

  1. Symbols can be used as object keys. Only strings and symbols can be used as object keys.
  2. No two symbols are ever equal.
const symbol1 = Symbol();
const symbol2 = Symbol();

symbol1 === symbol2; // false

const obj = {};
obj[symbol1] = 'Hello';
obj[symbol2] = 'World';

obj[symbol1]; // 'Hello'
obj[symbol2]; // 'World'

Although the Symbol() call makes it look like symbols are objects, symbols are actually a primitive type in JavaScript. Using Symbol as a constructor with new throws an error.

const symbol1 = Symbol();

typeof symbol1; // 'symbol'
symbol1 instanceof Object; // false

// Throws "TypeError: Symbol is not a constructor"
new Symbol();

#javascript #es6 #programming #developer

Earl Fay

Earl Fay

1597655940

The Complete Guide to JS Symbols ES6

In this video I cover the new-ish primitive type: Symbols! What are they? How does they work? When would you use them? Towards the end of the video I show three different use cases/examples of Symbols in action. To help decide on future video topics, make sure to subscribe and turn on notifications!

#javascript #es6 #web-development #programming #developer