1.作用域
- 每一个变量、函数都有其作用的范围,超出作用不得使用,这个叫做作用域。
- 在javascript中,其对作用域的划分都是通过函数function来实现的,在函数内部的区域,我们就称之为“局部作用域”,在函数外部的区域,我们就称之为“全局作用域”
- es6中新增了
块级作用域
(大括号,比如:if{},for(){},while(){}…)
例如:
2.自由变量
自由变量的概念: 当前作用域没有定义的变量
3.作用域链
自由变量的向上级作用域一层一层查找,直到找到为止,最高找到全局作用域,就形成了作用域链。
例如:
var a = 1
function fn1(){
function fn2(){
console.log(a)
}
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
var fn = fn1()
fn() //输出2
解析:var fn = fn1(),执行函数fn1(),因为return fn3,再执行函数fn3(),再执行函数fn2(),再执行console.log(a),那么a是多少呢?fn2里没有变量a,去fn2的上一级(声明fn2的地方)fn1里去找,找到了 var a=2, 那么console.log(2),输出了2。
4.变量提升
var声明的变量,function声明的函数存在变量提升
let const 不会变量提升
1. javascript中声明并定义一个变量时,会把声明提前,以下会先打印出undefined,再打印出10
console.log(a)
var a = 10
console.log(a)
相当于就是
var a
console.log(a);//undefined
a = 10
console.log(a) //10
2.函数提升
js中创建函数有两种方式:函数声明式和函数字面量式。只有函数声明才存在函数提升!如:
console.log(f1); // function f1() {}
console.log(f2); // undefined
function f1() {}
var f2 = function() {}
只所以会有以上的打印结果,是由于js中的函数提升导致代码实际上是按照以下来执行的:
function f1() {} // 函数提升,整个代码块提升到文件的最开始<br>console.log(f1);
console.log(f2);
var f2 = function() {}
结语:基本上就是这样,要熟练掌握的话可以多做些练习,test:
console.log(f1());
console.log(f2);
function f1() {console.log('aa')}
var f2 = function() {}
(function() {
console.log(a);
a = 'aaa';
var a = 'bbb';
console.log(a);
})();
5.我们可以在一道有趣的面试题中了解变量提升和函数提升
需要了解的内容:
① 在浏览器进行编译的时候,变量声明和函数声明都会提升,并且函数声明的提升优先级大于变量声明的提升
② 函数表达式不可提升
var getName = function() {
console.log(4);
};
function getName() {
console.log(5);
}
getName(); //4
相当于如下:
function getName() { // 函数声明的提升大于变量声明的提升
console.log(5);
}
var getName;
getName = function() { // 函数表达式不会提升
console.log(4);
};
getName(); // 4