All posts by admin

Symbols in JS, and why

ref –

  • https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/
  • https://flaviocopes.com/javascript-symbols/
  • https://medium.com/intrinsic/javascript-symbols-but-why-6b02768f4a5c
  • https://javascript.info/symbol

Basics info

A symbol represents a unique identifier.
A value of this type can be created using Symbol():

Upon creation, we can give the symbol a description (also called a symbol name) , mostly useful for debugging purposes:

Symbols are guaranteed to be unique. Even if we create many symbols with the same description, they are different values. The description is just a label that doesn’t affect anything.

For instance, here are two symbols with the same description – they are not equal:

…But if we used a string “id” instead of a symbol for the same purpose, then there would be a conflict:

“Hidden” properties

Symbols allow us to create hidden properties of an object, that no other part of code can accidentally access or overwrite.

For instance, if we’re working with user objects, that belong to third-party code. We’d like to add identifiers to them.

Let’s use a symbol key for it:

What’s the benefit of using Symbol(“id”) over a string “id”?

As user objects belong to another code, and that code also works with them, we shouldn’t just add any fields to it. That’s unsafe. Notice the public use of string “name” to change user object value.

But a symbol cannot be accessed accidentally, the third-party code (hidden away in some module) cannot be accessed by us.

Also, imagine that another script wants to have its own identifier inside ‘user’, for its own purposes. That may be another JavaScript library so that the scripts are completely unaware of each other.

Then that script can create its own Symbol(“id”), like this:

Now, there will be no conflict between the original and other id values, because symbols are always different, even if they have the same name.

…But if we used a string “id” instead of a symbol for the same purpose, then there would be a conflict:

Symbols in a literal

If we want to use a symbol in an object literal {…}, we need square brackets around it.

Like this:

That’s because we need the value from the variable id as the key, not the string “id”.

Symbols are skipped by for…in

For…in iterates through all the indexes of an object/array.
However, symbolic properties do not participate in for..in loop.

For instance:

Object.keys(user) also ignores them.

That’s a part of the general “hiding symbolic properties” principle.

If another script or a library loops over our object, it won’t unexpectedly access a symbolic property.

In contrast, Object.assign copies both string and symbol properties:

There’s no paradox here. That’s by design. The idea is that when we clone an object or merge objects, we usually want all properties to be copied (including symbols like id).

Other Stuff

object keys could only be strings

If we ever attempt to use a non-string value as a key for an object, the value will be coerced to a string. We can see this feature here:

A symbol is a primitive which cannot be recreated

They are useful in situations where disparate libraries want to add properties to objects without the risk of having name collisions.

For example:

By making use of symbols, each library can generate their required symbols upon instantiation. Then the symbols can be checked on objects, and set to objects, whenever an object is encountered.

For this reason, it would seem that symbols do benefit JavaScript.
However, you may be wondering, why can’t each library simply generate a random string, or use a specially namespaced string, upon instantiation?

Well, you’d be right. This approach is actually pretty similar to the approach with symbols. Unless two libraries would choose to use the same property name, then there wouldn’t be a risk of overlap.

Object.keys() does not return symbols

Here is an example of using a symbol as a key within an object:

Notice how they are not returned in the result of Object.keys(). This is, again, for the purpose of backward compatibility. Old code isn’t aware of symbols and so this result shouldn’t be returned from the ancient Object.keys() method.

In addition to that, Symbols do not show up on an Object using for in, for of or Object.getOwnPropertyNames – the only way to get the Symbols within an Object is Object.getOwnPropertySymbols:

This means Symbols give a whole new sense of purpose to Objects – they provide a kind of hidden under layer to Objects – not iterable over, not fetched using the already existing Reflection tools and guaranteed not to conflict with other properties in the object!

Symbols are completely unique…

By default, each new Symbol has a completely unique value. If you create a symbol (var mysym = Symbol()) it creates a completely new value inside the JavaScript engine. If you don’t have the reference for the Symbol, you just can’t use it.
This also means two symbols will never equal the same value, even if they have the same description.

Well, there’s a small caveat to that – as there is also another way to make Symbols that can be easily fetched and re-used: Symbol.for(). This method creates a Symbol in a “global Symbol registry”. Small aside: this registry is also cross-realm, meaning a Symbol from an iframe or service worker will be the same as one generated from your existing frame:

Cross Realm

Problem:

main usage

Macros
As a unique value where you’d probably normally use a String or Integer:
Let’s assume you have a logging library, which includes multiple log levels such as logger.levels.DEBUG, logger.levels.INFO, logger.levels.WARN and so on. In ES5 code you’d like make these Strings (so logger.levels.DEBUG === ‘debug’), or numbers (logger.levels.DEBUG === 10). Both of these aren’t ideal as those values aren’t unique values, but Symbols are! So logger.levels simply becomes:

A place to put metadata values in an Object

You could also use them to store custom metadata properties that are secondary to the actual Object. Think of this as an extra layer of non-enumerability (after all, non-enumerable keys still come up in Object.getOwnProperties). Let’s take our trusty Collection class and add a size reference, which is hidden behind the scenes as a Symbol (just remember that Symbols are not private – and you can – and should – only use them in for stuff you don’t mind being altered by the rest of the app):

WeakSet and Set in JS

Generally, references to objects are strongly held in JavaScript, meaning that as long you have a reference to the object, it won’t be garbage-collected.

Here, the literal object has retain count of 1 because ref is pointing to it.

A Set can hold characters, numbers, symbols, and objects.

Primitive values are not referenced, rather it literal values.
If we were to add an object, it will be strongly referenced.
That’s why for Sets, we can add them all. It goes with the meaning of Set, which is strongly hold on to the values/objects.

Let’s test this with some code.

Set

Double click on the index.html to run it. Click the button and you’ll see the Set’s data being displayed. The Set has a weak reference to the objects we declared. Since our output is currently displayed, there is a strong reference to the Set data structure. In order to demonstrate our Set and weak Set, we must get rid of any external references.

et’s clear the console so that we let the JS engine know to get rid of this string reference.

Once the console is empty, let’s click on the Performance tab. This way, the garbage collector will collect any JS objects with zero references on them.

Now go back to the console, click on the button, and look at the Set’s data output. There are still two objects in there. That is because Set has a strong reference to our objects. These objects still has a retain count of 1. Thus, when the garbage collector saw this, it didn’t garbage collect.


Set
0: value: {}
1: value: {}
__proto__: Set

When we point objectB away to null, the literal object decreases its retain count to 1. It is still pointed to by Set. Thus, when the garbage collector comes around, it sees that the object is still valid at 1. Thus, it will not collect.

WeakSet

Currently, WeakMaps and WeakSets are the only way to kind-of-weakly reference an object in JavaScript. When it references an object, it does not increment an object’s retain count. Thus, adding an object as a key to a WeakMap or WeakSet doesn’t prevent it from being garbage-collected.

Now let’s replace our Set with a WeakSet.

Run the index.html and clear the console of any output. Click on Performance tan and click on the garbage icon to run the garbage collector.

Because our Weakset weakly retains our literal object B, and reference B already pointed it away to null, the retain count lowers to 0. Hence when our garbage collector runs, it will see that literal object B’s retain count is 0, and collects it.

Push the button again and we see that our Set only has literal Object A.


WeakSet
0: value: {}
__proto__: WeakSet

Due to this characteristic, WeakSet only makes sense if it is working with objects. Thus, they only take objects. If you were to try to set a primitive value, it will give you an error.

Because WeakMpa’s reference does not increase the retain count, when we re-point our objectB reference to null, the literal object decreases from 1 to 0. Thus, when the garbage collector comes, it’ll see that this object is 0 and collects it.

SSO strategies, Oauth2 and SAML standards

ref – https://www.mutuallyhuman.com/blog/choosing-an-sso-strategy-saml-vs-oauth2/
https://developer.okta.com/blog/2017/06/21/what-the-heck-is-oauth
https://docs.expo.io/versions/latest/sdk/app-auth/?redirected
https://docs.expo.io/versions/latest/sdk/auth-session/

https://stackoverflow.com/questions/1087031/whats-the-difference-between-openid-and-oauth

OAuth-OpenID: You’re Barking Up the Wrong Tree if you Think They’re the Same Thing

What is SSO?

Single sign-on is a property of access control of multiple related, yet independent, software systems. With this property, a user logs in with a single ID and password to gain access to any of several related systems.

In order to provide a user with a single sign-on experience, a developer needs to implement an SSO solution. Over the years there have been many attempts at achieving SSO. One modern and popular choice is 0Auth2.

Client – this is your browser, mobile app, desktop app, or server-side app. It tries to interact with the Resource Server.

Service Provider (Resource Server) – this is the web-server you are trying to access data from.

Identity Provider (Authorization Server) – this is the server that owns the user identities and credentials. It’s who the user actually authenticates and authorizes with.

The authorization grant is a temporary code that the client will exchange for an access token.

A – a user opens their web-browser and goes to MyPhotos.com which stores all of their photos.

MyPhotos.com doesn’t handle authentication itself, so the user is redirected to the Authorization Server with a request for authorization. The user is presented with a login form and is asked if they want to approve the Resource Server (MyPhotos.com) to act on their behalf. The user logs in and they are redirected back to MyPhotos.com.

B – the client receives an authorization grant code as a part of the redirect.

C – the Client then uses that authorization grant code to request an access token from the Authorization Server.

D – if the authorization grant code is valid, then the Authorization Server grants an access token. The access token is then used by the client to request resources from the Resource Server (MyPhotos.com).

E – MyPhotos.com receives the request for a resource and it receives the access token. In order to make sure it’s a valid access token, it sends the token directly to the Authorization Server to validate. If valid, the Authorization Server sends back information about the user.

F – having validated the user’s request MyPhotos.com sends the requested resource back to the user.

OAuth2 provides three other flows (or what they call authorization grants) which work for slightly different scenarios, such as single-page javascript apps, native mobile apps, native desktop apps, traditional web apps, and server-side applications where a user isn’t directly involved but they’ve granted you permission to do something on their behalf.

  • Authentication means confirming your own identity. Proving who are you.
  • Authorization means granting access to data/functionality, without having to deal with original authentication

OAuth could be used in external partner sites to allow access to protected data without them having to re-authenticate a user.
OAuth was created to remove the need for users to share their passwords with third-party applications

OpenID was created for federated authentication, that is, letting a third-party authenticate your users for you, by using accounts they already have

Example

ref – https://dzone.com/articles/sso-login-key-benefits-and-implementation

How SSO Login Works
Let’s look at an ideal scenario before going into the nitty-gritty of how SSO login works. Three apps have been developed separately: App FOO, App BAR, and App BAZ. They are also hosted on three different domains: foo.com, bar.com and baz.com, respectively.

Challenge: Users have to enter different usernames and passwords for the three different apps to gain access to certain resources.

Proposed solution: Eliminate the different login systems that are present. Users should be able to log in to foo.com and then be signed in to bar.com and baz.com automatically without having to re-enter their authentication credentials.

SSO login to the rescue: With SSO login, a central authentication server needs to exist. Let’s call our central authentication server foobarbaz.com. This is how the process flow will look in this scenario:

The user accesses foo.com.

The user is redirected to foobarbaz.com, where an authentication-related cookie is generated.

The user navigates to bar.com.

The user is redirected to foobarbaz.com.

foobarbaz.com checks whether the user already has an authentication-related cookie and redirects the user back to bar.com, providing access to its features and content.

The same process applies to baz.com.

The simple take-away concept is that there is one central domain through which authentication is performed, and then the session is shared with other domains in some secure way e.g., a signed JSON Web Token (JWT).

this context (strict, non-strict, arrow)

es5

In non-strict environment, the ‘this’ keyword is bound to the context that is calling it
Context refers to the object to which a function belongs.

Yet when ‘this’ is inside of a function:

  • either stand-alone function
  • or within another method

it will always refer to the window/global object

stand-alone

…within method

Use strict

However, if you were to use strict mode, ‘this’ inside functions that are standalone, or within a method, would reference undefined

standalone functions within functions.
functions within methods

es6

With arrow functions, ‘this’ is lexically bound. It means that it uses ‘this’ from the code that contains the arrow function. In other words, it always uses ‘this’ from the parent scope.

class Greetings

In the class Greetings, for the constructor function’s this, we see that the parent scope’s ‘this’ is class Greetings. Thus, the ‘this’ references the instance Greetings.

In the method ‘print’, the parent scope is the constructor function. The constructor function’s ‘this’ is the instance (Greetings).

In the private method ‘haha’, the parent scope is also the constructor function. The constructor function’s ‘this’ is the instance (Greetings).

in setTimeout, the callback function’s ‘this’ parent scope is the private function haha. As mentioned above, private function haha’s context is the instance (Greetings).

In the next example, we are executing a callback. We are using an es5 function. es5 function ‘this’ references the object that is calling it. In our case, the setTimeout’s context is executing this callback function. Thus, ‘this’ references a Timeout instance.

Finally, we have the method ‘print2’. Since its an arrow function, its parent scope is class Greetings. Hence its ‘this’ references the instance (Greetings).

Literal Object bracket is NOT lexical scope

Our arrow function uses ‘this’ from the lexical scope that contains the arrow function. In the case of arrow function x, bar is the literal object that contains our arrow function.

It is NOT a lexical scope

Hence, bar’s this comes from the lexical scope that is the global scope. Global scope’s this is {}. Hence that is what the ‘this’ is inside of arrow function x.

In this example, we have a literal object. Then we have es5 function bar. The ‘this’ is bound to the calling context, which is literal obj. That is the ‘this’ inside function bar is ‘obj’.

Then, inside function bar, we have es6 arrow function. Arrow function says ‘this’ is bound to its lexical parent. Hence, since its lexical parent is bar’s this, it references literal obj. Thus that’s why in arrow function x, the ‘this’ also references ‘obj’.


output:

— obj calling function bar —
{ bar: [Function: bar] }
— in arrow function —
{ bar: [Function: bar] }

ref – https://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions

Our arrow function uses ‘this’ from the code that contains the arrow function The containing code is the literal object.
Since the literal object itself has no ‘this’, we cannot say it will log profile. Instead, the ‘this’ of literal object ‘profile’ is the global scope. And ‘this’ at global scope is {}

Lots of times, I would mistakenly believe that it should be literal object ‘profile’. That would be true in es5 function because it binds ‘this’ to the calling object as shown in the above example.

However, since we’re dealing with es6 arrow function, we bind ‘this’ to the parent scope’s this. NOT the parent object.

Hence, we cannot bind it to the literal object profile. We can only bind it to profile’s ‘this’.

Literal objects do not have ‘this’ context. So profile’s this defaults to global {} because literal object profile is at the global scope.

click handlers

means that when the element is clicked, the function ‘test’ is fired. But this function test is bound as an event handler, so ‘this’ is set to the reference to the button DOM element.

In test function’s definition, the this is the global obj, as it is when any function that’s not an event handler or an object method is.