'use strict' not stopping hoisting in function scope

Variable declarations (i.e. var x;) are valid for the entire scope they are written in, even if you declare after you assign. This is what is meant by "hoisting": the var x; is hoisted to the beginning of the scope, and the assignment x = 6; is fine because x has been declared somewhere in that scope.

Strict mode does not change any of this. It would throw an error if you omitted the var x; declaration altogether; without strict mode, the variable's scope would implicitly be the global scope.

In ES2015 (a.k.a. ES6), hoisting is avoided by using the let keyword instead of var. (The other difference is that variables declared with let are local to the surrounding block, not the entire function.)