学习js就无法避免的要学习到闭包这个概念,而学习闭包之前理解好作用域和作用域链是很有帮助的。
作用域:
对于变量的作用域每个人都不会陌生,而根据作用域则有了所谓的全局变量和局部变量。
下面是一段代码:
function test (value) { var i = 0 ; if ( typeof (value) == "number"){ var j = 0 ; for (var k = 0 ; k < 10 ; k++ ) { console.log(k); } console.log(k) } console.log(j) console.log(i) }
他们的输出是什么样子呢
第一个k的输出 是数字 0 ~ 9 第二个k的输出 是 10 j输出是 undefined i输出是 0
js的函数作用域是指在函数内声明的所有变量在函数体内是始终可见的,让我感觉好玩的是,js里变量在声明之前已经可用,这种特性在js里称为声明提前,也就是在js函数里声明的所有变量都被提前到函数体的顶部,
例:
var value = " all" function test () { console.log(value); var value = "new"; console.log(value); }
输出
可能大家会认为第一个会输出all 其实是undefined 第二个是new
由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就局部变量会覆盖全局变量,,只有执行到var的时候才会被真正赋值。
作用域链:
js是一门基于词法作用域的愿,全局变量在整个程序中都是有定义的,而局部变量在她的函数体内及其内部嵌套的函数内都是有定义的,我们可以换个角度来理解作用域,每一段js代码都有一个与之关联的作用域链,作用域链是什么呢,就是一个对象列表或者链表,这组对象定义了了这段代码的作用域中的变量。
假设我们需要查找一个a的值,就会从程序的作用域链中的第一个对象中查找,如果有,直接调用,如果没有继续查找第二个,如果将作用域链查找完毕,都没有找到,就会抛出引用错误。
作用域链的理解对于之后的闭包概念的理解很重要,接下来再去理解闭包的概念