/*
* 变量提升:在当前上下文中(全局/私有/块级),JS代码自上而下执行之前,浏览器会提前处理一些事情(可以理解为词法解析的一个环节,词法解析一定发生在代码执行之前)
* 会把当前上下文中所有带var/function关键字的进行提前的声明或者定义
* var a = 10
* 声明declare: var a
* 定义defined: a = 10
* 带var的只会提前的声明
* 带function会提前的声明定义
*/
/*
* 代码执行之前:全局上下文中的变量提升
* var a
*/
// console.log(a)
// var a = 12
// a = 13
// console.log(a)
/*
* 全局上下文中的变量提升
* func=函数 函数在这个阶段赋值都做了
*/
// func()
// var func = function () {
// // 其实项目中建议用函数表达式创建函数,因为这样在变量提升阶段只会声明func,不会赋值
// consoel.log('OK')
// }
// func()
var func = function AAA() {
// 把原本作为值的函数表达式匿名函数"具体化"(虽说是起了名字,但是这个名字不能在外面访问 => 也就是不会在当前上下文中创建这个名字)
// 当函数执行,在行程的私有上下文中,会把这个具体化的名字作为私有上下文中的变量(值就是这个函数)来进行处理
console.log('OK')
// console.log(AAA)
// AAA()
}
// AAA()
func()
/*
* EC(G)变量提升
*/
console.log(a)
a = 13
console.log(a)
/*
* EC(G)变量提升 只有var/function会变量提升(ES6中的let和const不会)
*/
console.log(a)
let a = 12
a = 13
console.log(a)
/*
* 基于"var或者function"在"全局上下文"中声明的变量(全局变量)会"映射"到GO(全局对象window)上一份,作为他的属性,而且接下来是一个修改,另外一个也会跟着修改;
*/
var a = 12
console.log(a)
console.log(window.a)
window.a = 13
console.log(a)
/*
* EC(G): 全局上下文中的变量提升
* 不论条件是否成立,都要进行变量提升(细节点:条件中带function的在新版本浏览器中只会提前声明,不会再提前的赋值了)
* [老版本]
* var a
* func=函数
* [新版本]
* var a
* func
*/
// console.log(a, func)
if (!("a" in window)) {
//=>"a" in window 检测a是否为window的一个属性 !true = false
var a = 1
function func() {}
}
console.log(a)
fn();
function fn() { console.log(1); }
fn();
function fn() { console.log(2); }
fn();
var fn = function() { console.log(3); }
fn();
function fn() { console.log(4); }
fn();
function fn() { console.log(5); }
fn();
var foo = 1
function bar() {
if (!foo) {
var foo = 10
}
console.log(foo)
}
bar()