Skip to content

Instantly share code, notes, and snippets.

@abhisekp
Last active April 18, 2017 15:23
Show Gist options
  • Select an option

  • Save abhisekp/c92ae4e5f142b259ff06469dfb42dc75 to your computer and use it in GitHub Desktop.

Select an option

Save abhisekp/c92ae4e5f142b259ff06469dfb42dc75 to your computer and use it in GitHub Desktop.
JavaScript Concepts — http://bit.ly/js-concepts

JavaScript Concepts

— by Abhisek Pattnaik <[email protected]>
JavaScript Concepts
  1. What is a Closure?
  2. [[Prototype]] vs Prototype (in progress)
  3. Express.js Middleware Simplified

Coming Soon

  • Why prototype property is automatically created on function creation?
  • What is the use of constructor property in prototype property (<object>) of functions?
  • How inheritance works in JavaScript?
Watch Marcus Phillips: Secrets and Lies about JavaScript classes

https://www.youtube.com/watch?v=_JJgSbuj5VI
⚠️ WARNING: It might be a bit difficult to watch the whitescreen and unclear voice.

Todo

Closure

Closure

All the functions in JS are closures and the reason is JS stores a binding to the outer lexical scope variables in the function context and not just a copy of the outer scope at the time of declaration.

E.g.

let age = 1
const getAge = () => age

console.log(age) // 1
console.log(getAge()) // 1

age = 10
console.log(age) // 10
console.log(getAge()) // 10

This is how JS works!!

Here getAge is a closure.
Had JS stored only a copy of the variable without any reference binding to the original variable, then we wouldn't have said it a closure. e.g. (only if this was real for JS)

let age = 1
const getAge = () => age

console.log(age) // 1
console.log(getAge()) // 1

age = 10
console.log(age) // 10
console.log(getAge()) // 1

Note the last console log. Here getAge function gives the value of the snapshot of the variable it had stored while it was declared and not the value of the changed value. Hence, had JS behaved this way, we wudn't consider getAge as a closure.

(This is just a fake example. This is not how JS works)

That's all to closure.

Express.js Middleware Simplified

ExpressJS Middleware

Imagine a request sent from the woman side (see the train figure) and the response will be served from the man side. Here, the MIDDLEWARE is person in the middle through which the request is going to be passed. So he can manipulate the request accordingly and pass it forward.

👨 RESPONSE ← 🚋🚋🚋:feelsgood:🚋🚋 ← REQUEST 👩

 

Why this MIDDLEWARE pattern?

In this pattern the middleware perform some task and are responsible only for that task. This results in manageable and declarative code i.e. You only need to specify WHAT a middleware should do according to your requirement without worrying about how it is implemented.

e.g.
Imagine a request made with a query parameter - autorun. And it takes two values i.e. enabled or disabled. If the value is disabled, then convert it to false. Otherwise, convert it to true.

function autorunMiddleware(req, res, next) {
  var autorun = req.query.autorun;

  if (autorun === 'disabled') {
    req.query.autorun = false;
  } else {
    req.query.autorun = true;
  }

  next();
}

Now the next middleware can simply check for a boolean value and work accordingly.
e.g.

app.get('/', autorunMiddleware, function (req, res) {
  if (!req.query.autorun) {
    res.send('Autorun is disabled.');
  } else {
    res.send('Autorun is enabled.');
  }
});

Here, autorunMiddleware is run and then the next callback function is run which sends the response.

Note: All internal properties or entities are written using [[...]] notation.

[[Prototype]] attribute

— the internal [[Prototype]] attribute of every object

All objects have this internal [[Prototype]] attribute. This is the same __proto__ property.

in progress

prototype property

— the prototype property of functions

Imagine an internal [[Function]] constructor which is used to create a function object.

/*************************

function [[Function]](name) {
    this.length = 0
    this.name = name || 'anonymous'
    this.prototype = { constructor: this }
}

**************************/

So when a new function is created such as

function f() {}

internally, it runs

/*********************

f = new [[Function]]('f')

*********************/

which creates an instance of [[Function]] object which is of function type with the name as 'f' i.e.

typeof f === 'function' // true
f.name // 'f'

Now let us see the properties of the newly created function f object

Object.getOwnPropertyNames( f ) // ['length', 'name', 'prototype']

NOTE: if you see additional properties such as arguments and caller, then, it is because the function might be created using the new Function constructor (and NOT the internal [[Function]] constructor directly).

As you can see, there is a length, name and prototype properties. These properties are pretty popular 😉
Let us have a look at their values.

console.log(f.name) // "f"
console.log(f.length) //0
console.log(f.prototype) // { constructor: f }

Conclusion

Internal [[Prototype]] attribute of every object and prototype property of functions are two distinct entities. Do not confuse between them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment