Javascript function part 1/4: a "first-class" citizen

This tutorial is a part of the Learn everything about Javascript in one course.

Function is a "first-class" citizen in Javascript

A programming language is said to have first-class functions when functions in that language are treated like any other variable. As the metaphor "first class" in airline industry, Javascript function is well taken care of, hence, provide a lot flexibity and ways to use.

"First class" attribute, we can Example
Assign a function to a variable const myFunc = () => { // do something }
Pass a function as an Argument In this example, func1 is passed to func2 as a variable.
const func1 = () => { // do something }
const func2 = (func1) => { func1() }
Return a function const func3 = () => () => { // do something }
function.js
// Function is a "first-class" citizen in Javascript

// Assign a function to a variable
const myFunc = () => {
  console.log('running statements in myFunc!')
}
myFunc() // running statements in myFunc!

// Pass a function as an Argument
const func1 = () => console.log('running func1')
const func2 = (func1) => {
  func1()
  console.log('running func2')
}
func2(func1)
// running func1
// running func2

// Return a function
const func3 = () => console.log('running func3')
const func4 = () => {
  console.log('running func4')
  return func3
}
const a = func4() // running func4
a() // running func3

Object function is diffrerent from arrow function

Object function can be used to create a "blueprint" of object. Newly created objects using this blueprint will have the same properties and methods defined in this blueprint.

Arrow function is designed for pure function purpose. It can't be used to create object blueprint.

Object function Arrow function
Available in Javascript version ES5 and before ES6 and beyond
Declaration function myFunc1() { // do something } const myFunc1 = () => { // do something }
Used as normal function
Create object blueprint
(constructor)
function.js
// Object function used to create object blueprint
function MySpecialDataStucture() {
  console.log('running blueprint')
  this.property1 = '123'
  this.method1 = function() {
    console.log('running method 1')
  }
}
const specialDs = new MySpecialDataStucture() // running blueprint
console.log(specialDs) // MySpecialDataStucture { property1: '123', method1: [Function] }
console.log(specialDs.property1) // 123
specialDs.method1() // running method 1

The "this" keyword refers to current context object

this keyword refers to current context. In Javascript current context is represented by an object and the this keyword is that object. this keyword usage will be disable with 'use strict' directive. The following table presents some example of this contexts.

Context Example this refer to
within a function in object function the object itself
within a browser window Chrome or Safari console the current window object
within a file an .js file the current file object
good to know, but do not use!
this_keyword.js
// this keyword called within an object function refers itself
function MySpecialDataStucture() {
  console.log(this) // MySpecialDataStucture {}
  this.property1 = '123'
  console.log(this.property1) // 123
  this.method1 = function() {
    console.log('running method 1')
  }
  console.log(this) // MySpecialDataStucture { property1: '123', method1: [Function] }
}
const specialVariable1 = new MySpecialDataStucture()

// specialVariable1 is created based on a "MySpecialDataStucture" blueprint
// so it has everything defined in the blueprint
console.log(specialVariable1) // MySpecialDataStucture { property1: '123', method1: [Function] }


// we can create as many new object based on this blue print as wanted
const specialVariable2 = new MySpecialDataStucture()
console.log(specialVariable2) // MySpecialDataStucture { property1: '123', method1: [Function] }




// DO NOT USE IN PRODUCTION - FOR LEARNING PURPOSE ONLY
// this way of usage exposes a high security threat
// we can call "this" keyword here. it will represent this file
console.log(this) // {}, this file currently has no property nor method

// we can always add property and method for this file
this.property = 456
this.method = () => {
  console.log(`running a method from this_keyword.js`)
}
// and call them right here
console.log(this.property) // 456
this.method() // running a method from this_keyword.js

The "new" operator is used to create an object based on blueprint

The new operator is put in front of constructor (blueprint) to create a new object based on that blueprint.

new_operator.js
// define an object blueprint "MyCustomDataStructure"
function MyCustomDataStructure() {
  this.property1 = 123
  this.property2 = 'abc'
  this.method1 = () => {
    console.log('running method1')
  }
  this.method2 = () => {
    console.log('running method2')
  }
}

// you can create as many object based on blueprint as wanted
const customDs1 = new MyCustomDataStructure()
const customDs2 = new MyCustomDataStructure()

// they have the same property(ies) and method(s)
console.log(customDs1)
// MyCustomDataStructure {
//   property1: 123,
//   property2: 'abc',
//   method1: [Function],
//   method2: [Function]
// }
console.log(customDs2)
// MyCustomDataStructure {
//   property1: 123,
//   property2: 'abc',
//   method1: [Function],
//   method2: [Function]
// }

"Arrow" in arrow function used as return shorthand

Without block statement {}, arrow => in arrow function can be used as shorthand to return a value.

Use Example Meaning
With statement block {} const func1 = () => { // do something } Normal function definition syntax
Without statement block {} const func1 = () => 'b'
(function return 'b' when runs)
Function return the value right after arrow =>.

The following syntaxes are the same to define a funtion returns value 'b':

Object function Arrow function with return Arrow function shorthand
function() { return 'b' } () => { return 'b' } () => 'b'
arrow_function.js
// Arrow => in arrow function

// no statement block {} means return the value after arrow
const func1 = () => 'b'
console.log(func1()) // b

Self invoking function, declare and run function right away

We can declare a function and run it immediately.

arrow_function.js
// Self invoking function, declare and run function right away

// we can replace this
function myFunc1 () {
  console.log('running myFunc1...')
}
myFunc1() // running myFunc1...


// with this self invoking "object" function
// notice the semi-colon ";", because we are not using it at every line end,
// we need to put it in front of any self-invoking function
;(function myFunc2() {
  console.log('running myFunc2...')
})() // running myFunc2...


// with this self invoking "arrow" function
  ;(() => console.log('running myFunc3...'))() // running myFunc3...
/* ^                                       ^^^
   |                                       |||
   |                                       | - pair of open-close
   |                                       |   parenthesis means "invoke"
   |                                       |
   -----------------------------------------
                     |
            wrap declaration in parenthesises ()
*/

Two variable scopes: global scope and function scope

Variable scope is where a variable can be used.

  • Only 2 types of scopes in Javascript: global scope and function scope.
  • Function scope variable will be used if it has same name with a Global scope variable.
Global scope Function scope
Variable declared Outside function Within a function
Variable can be used Anywhere Within function it defined

If a function is defined inside another function, inner function can access variable declared at outer function. But outer function can not access variable declared at inner function. In the following example, Function2 is defined inside Function1.

Variable declared at Global access Function1 access Function2 access
(inside Function1)
Global
Within Function1
Within Function2
variable_scope.js
// Two variable scopes: global scope and function scope

// global scope variable example
const str = 'Hello' // "str" can be used anywhere hence "global scope"

function greet(name) {
  console.log(str + ' ' + name) // note that "str" is used here
}
greet('Mr. Stark') // "Hello Mr. Stark"



// function scope variable example

const greet2 = (name) => {
  const str2 = 'hello' // "str2" only available to use in "greet2" function
  console.log(str2 + ' ' + name)
}
greet2('Captain America') // "hello Captain America"


// print out global scope "str" ok
console.log(str) // Hello

// un-comment to see error
// str2 only known to function greet2
// so it will give an error if we try to access it here

// console.log(str2) // ReferenceError: str2 is not defined

Bind given variable to function's "this", method bind()

Syntax function.bind(variable)

Method bind will return a new function which is the same with the original function, the only difference is this of new function is the variable passes in.

bind_method.js
// Bind given variable to function's "this", method bind()

const obj = { // we will pass this "obj" to "this"
  prop1: 'hello',
  method1: () => console.log('running method 1'),
}

function myFunc() {
  console.log('running myFunc')
  console.log(this) // "this" will be "obj" after bind()
}

const myFunc2 = myFunc.bind(obj) // myFunc2's "this" is now "obj"

myFunc2()
// running myFunc
// { prop1: 'hello', method1: [Function: method1] }

Summary

  • First class function properties: assign, pass and return function around as variable.
  • Object function is also a constructor, arrow function is not.
  • Javascript only has 2 types of variable scope: global scope and function scope. They can nest like onion rings and accessibility is one way toward to the center.