コールスタック
言葉の定義としては実行中のコードがたどってきたコンテキストの積み重ねになります。
function a() {
}
function b() {
a();
}
function c() {
b();
}
c();
この関数を実行した際にはまず、グローバルコンテキストが生成されます。次にcの関数が呼ばれる際にcの関数コンテキストが生成されます。次にbの関数が呼ばれるのでbの関数コンテキストが生成され、同様にaのコンテキストが生成されます。イラストで確認しましょう。

実行中のコンテキストは常にコールスタックの一番上のコードになります。aのコードの実行が終了するとaは消滅し、次にb,c,グローバルの処理まで進み最後には全て消滅します。
実際にブラウザで確認するとイラストと同様の現象が確認することができます。(※ここでのグローバルコンテキストはanonymousになります。)
ホスティング
コンテキスト内で宣言した変数や関数の定義をコード実行前にメモリーに配置すること。具体的な様子をブラウザから確認しましょう。
まず関数aを用意し、呼ばれたタイミングでconsoleに出力するようにします。
function a() {
console.log("called")
}
関数を呼び出してみましょう。
function a() {
console.log("called")
}
a();
出力を確認できます。
関数の呼び出しを宣言前に書いてみましょう。
a();
function a() {
console.log("called")
}
同様に出力を確認できます。
この理由は、関数や変数の宣言はコードの実行前(この場合はa()のこと)に既にメモリに配置されているからです。なので関数の宣言前に関数の実行を書いたとしても問題なく関数は実行されます。
続いて変数の場合も見ていきましょう。まず、varから見ていきましょう
var a = "called"
console.log(a)
console.log(a)
var a = "called"
値が未定義という結果になりました。これはconsole.logで値を呼んだ時、まだbに値が格納されていないから起こる現象になります。
let,constについても見てみましょう。
console.log(a)
let a = "called"
エラーが出力される結果になりました。これはaというメモリ自体は確保されていますが、undefinedの初期化がJavaScriptエンジンで行われないからになります。
参考
Udemy: 【JS】ガチで学びたい人のためのJavaScriptメカニズム