JavaScript Definition III

Contents

  1. Function Invocation
  2. Arguments keywords
  3. Variable Environment
  4. Function Scope(lexical scope) vs Block Scope
  5. Issues with global variable
  6. Dynamic Scope vs Lexical Scope

1. Function Invocation

Programs are assigning memory and executing functions. For example, assigning a value to a variable and then running a function for the program to do something with those variables. Without functions, our programs would not do anything.

  • function declaration: function declaration is something that starts with function keyword.
  • function expression: function expression is something that starts declaring a variable with function value.
    • function expression is not hoisted.
// function expression
var sing = function(){
 console.log("It is defined");
}
  • function invocation: calling a function we do a function invocation by simply running the function with curly brackets.

when a function is invoked, we create a new execution context on top of our global execution context.

Function Invocation

Ways of invoking a function

  • general
  • by call() or apply()
  • Inside object
  • using a function constructor
function one() {
    return console.log(1);
}
const obj2 = {
    two: function () {
        return console.log(2);
    }
}
const obj3 = {
    three() {
        return console.log(3);
    }
}
const four = new Function('return console.log(4)');

// general
one();

// by call() or apply()
one.call();

// In object
obj2.two();
obj3.three();

// A function constructor
four();
1
1
2
3
4

Functions are objects

It is something that is not very common in other languages.

In JavaScript, I can add a new value in function.

function a() {
    console.log("ok");
}
a.hi = "hello";
console.log(a.hi);
hi

When we create a function, JavaScript create a special type of object is called a callable object.

2. Arguments keywords

There are many things that you can do with the arguments keyword that might make the compiler in the JavaScript engine less able to optimize the code.

arguments keywords look like an array but it is not really an array.

argument keyword to array

Array.from(arguments)

Arguments keywords

function a(year, location) {
  return console.log(arguments);
}
a("2020", "seoul")
[Arguments] { '0': '2020', '1': 'seoul' }

when we invoke the function we will get arguments object.

arguments keyword without parameter.

function a(){
 console.log(arguments);
}
a()
[Arguments] {}

with empty parameters we can get arguments because on each execution context we create a new arguments object.

3. Variable Environment

Variable Environment is a place that variables can live in different stack worlds. They all technically live in the JavaScript engine memory heap but they need to know how they related to between functions which functions have access to certain variables and some do not.

Variable Environment

function two() {
  console.log("function two: " + isValid);
}
function one() {
  var isValid = true;
  console.log("function one: " + isValid);
  two();
}
var isValid = false;
console.log(isValid);
one();
false
function one: true
function two: false

Each execution context has it own variable environment.

4. Function Scope(lexical scope) vs Block Scope

JavaScript has function scope (lexical scope) every time we create a function we create a new execution context which has its own variable environment. However, most other programming languages have something called block scope.

Function Scope

var isValid = false

if(!isValid){
 var function_scope = true
}

console.log(function_scope)
true
  • no error

Block Scope

var isValid = false

if(!isValid){
 let block_scope = true
}

console.log(block_scope)
ReferenceError: block_scope is not defined

JavaScript with After ES6 let, const keywords they allow us to use block scoping.

Actually, the variable itself let, const still in memory, but the JavaScript engine do not allow you to access it.

5. Issues with global variable

There are two main problems in global variable.

  1. limited space
    • Global variables are one of the main reasons for memory leaks.
  2. Variable collision

Variable collision

<script>var x = 1</script>
<script>var x = 2000</script>

In HTML file all these tags get combined essentially into one execution context which means everything is our the global execution context and overwrite each other. This creates a lot of bugs.

How to solve this? Module

6. Dynamic Scope vs Lexical Scope

Everything in JavaScript is actually lexically scoped where you write it to determine what we have available except for this keyword

const obj = {
  name: "Jay",
  sing: function() {
    console.log("a " + this.name);
    console.log("a " + this )
    var anotherFunc = function () {
      console.log("b", this.name);
      console.log("b", this);
    };
    anotherFunc();
  },
};

obj.sing();
a Jay
a {name:"Jay", sing:f{...}}
b undefined
b Object [global]
  • why b is undefined and get global object? because this keyword is not lexically scoped. It is dynamic scope that it matters how the function was called.

So, we need lexically scoped for this keyword.

1. with ES6

const obj = {
  name: "Jay",
  sing: function() {
    console.log("a " + this.name);
    console.log("a " + this )
    var anotherFunc =  () =>  {
      console.log("b", this.name);
      console.log("b", this);
    };
    anotherFunc();
  },
};

obj.sing();
a Jay
a { name: 'Jay', sing: [Function: sing] }
b Jay
b { name: 'Jay', sing: [Function: sing] }

2. with bind

const obj = {
  name: "Jay",
  sing: function () {
    console.log("a " + this.name);
    console.log("a " + this);
    var anotherFunc = function () {
      console.log("b", this.name);
      console.log("b", this);
    };
    return anotherFunc.bind(this);
  },
};

obj.sing()();
a Jay
a { name: 'Jay', sing: [Function: sing] }
b Jay
b { name: 'Jay', sing: [Function: sing] }

3. with self

const obj = {
  name: "Jay",
  sing: function () {
    console.log("a " + this.name);
    console.log("a " + this);
    var self = this;
    var anotherFunc = function () {
      console.log("b", self.name);
      console.log("b", self);
    };
    anotherFunc();
  },
};

obj.sing();
a Jay
a { name: 'Jay', sing: [Function: sing] }
b Jay
b { name: 'Jay', sing: [Function: sing] }

Leave a Reply

Your email address will not be published.

ANOTE.DEV