一、声明提前
javaScript在执行代码的时候会将所有的var声明的变量,放在作用域的顶部集中创建,赋值留在原地Tip:function声明函数的优先级最高,放在最顶部,再是声明的变量
**
- 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
- 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
- 函数声明和变量声明都会置顶,但是变量声明位于函数声明之后**
实战题
(1)var a = 100;function a(){console.log("hello")}a();//报错
(2)var a = 100;var a = function(){console.log("hello world")}a()//hello world
(3)var a = 100;function bar(){console.log(a)if(!a){var a = 20;}console.log(a)}bar()//undefined//20Tip:{}里面为一个作用域
//console.log(a);//var a = 20;//function a(){console.log("a");}//console.log(a);拆分:var a = function(){console.log("a")}var a;console.log(a); 变量a输出undefined,不会覆盖函数,输出函数a = 20;console.log(a); 变量a赋值后,将函数覆盖,输出20a();
二、作用域
在 JavaScript 中, 对象和函数同样也是变量。
在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。
JavaScript 函数作用域: 作用域在函数内修改。
2-1 局部变量
变量在函数内声明,变量为局部变量。
局部变量:只在固定的代码片段内可访问到的变量
// 此处不能调用 carName 变量function myFunction() {var carName = "Volvo";// 函数内可调用 carName 变量}
2-2 全局变量
变量在函数外定义,即为全局变量。
在任何地方都可以访问到的变量就是全局变量,对应全局作用域。在函数外声明。
var carName = " Volvo";// 此处可调用 carName 变量function myFunction() {// 函数内可调用 carName 变量}
如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。
以下实例中 carName 在函数内,但是为全局变量。
// 此处可调用 carName 变量function myFunction() {carName = "Volvo";// 此处可调用 carName 变量}
2-3 HTML 中的全局变量
在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。
//此处可使用 window.carNamefunction myFunction() {carName = "Volvo";}
2-4 块级作用域
- 从es6开始,js引入了块级作用域的概念,所谓块级作用域,就是声明在{}里面的变量
- 只有let const声明的变量才有块级作用域,var 声明的变量是没有块级作用域的
- 在同一个块里面,let的变量只能声明一次
{let a = 1; //局部变量}{//使用const声明的常量他的内存地址不可以被修改const b = {name:"haha"}; //局部变量b.name = "xx";}{var kk = 123; //全局变量}console.log(kk); //123console.log(a); //a is not defined
2-5 作用域链
- 只有函数可以制造作用域结构。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
- 将这样的所有的作用域列出来,可以有一个结构: 函数内指向函数外的链式结构。就称作作用域链。
- 作用域链: 变量的使用,从里向外,层层的搜索,搜索到了就可以直接使用了。层层搜索,搜索到0级作用域的时候,如果还是没有找到这个变量,结果就是报错
案例:
// 案例2function f1() {var num = 123;function f2() {console.log( num );}f2();}var num = 456;f1();

