在JavaScript中,作用域一般分成四种:全局作用域,词法作用域,动态作用域,函数作用域;
一)全局作用域:
变量的生命周期:该变量多长时间内保持有值状态;
全局变量:该变量存活的时间很长,且在整个程序中都能被访问到;
ps:在全局作用域中定义或者没有var定义的变量都是全局变量;
二)词法作用域:
定义:函数在定义时,当前的作用域或变成函数的内部属性,在函数被调用时所运行的作用域是当初被定义时的作用域,而不是函数被调用时所处在的作用域;
特点:函数被调用时,先从内部的词法作用域寻找变量,如果没有则通过作用域链寻找变量;
function A(){
var a=1;
var b=2;
return function(){
a=3;
console.log(a+"and"+b);
}
}
A()();
三)动态作用域:
定义:函数内部的作用域调用了函数外界的作用域对象(包括全局对象或者局部对象);
本质:动态作用域其实就是值得全局表映射;
eg:
function makBindFun(resolve){
return function(k,v){
var arr=obj[k]||[];
obj[k]=resolve(arr,v);
}
}
function A(k){
console.log(obj[k]);//在A函数总访问了外部的对象
}
(function(){
var B=makeBindFunc(function(arr,v){
arr.push(v);
return arr;
});
B("a",1);
A("a");
})()
缺点:动态作用域不太稳定,内部的值可能随时都被改变;
this:
定义:是指当前函数所在的作用域对象,一般是指window对象,也可以是指向封装好包含该函数的对象;
好处:每个声明的函数都具备this(即this指向是有意义的),因此可以动态改变this的指向;
eg:
window.name="dc";
let obj={name:"dragon"};
function A(){
console.log(this.name);
}
A()------>dc;
A.bind(obj)()------>dragon
case2:callback函数中的this是没有意义的,必须引进指定的作用域才有意义;
四) 函数作用域:定义:在函数所有var的声明变量在函数内处处可见,即变量的声明会提升到作用域顶部(变量提升);