\如需转载请注明来源
1.作用域
- 作用域声明提前:1 带var的和函数不管位置在哪里,在作用域中都会被提到最前面进行解析,把变量赋值为undefind。变量>函数是解析顺序,把变量赋值undefined,把函数解析成字符串,等号右边的值要等到JS的线程执行到。2 等号右边是在运行的时候才能解析得到。
- 作用域链:1 作用域访问未在自身内部定义的变量或者函数,会一层一层往父级以上的作用域找,换句话说只能由内而外。2 作用域链的定义与函数自身在哪里运行无关,和函数自身解析的位置才相关。
首先,JS是单线程任务语言,也就是说,JS是从上到下依次解析的。
其次函数才生成作用域,if或者for还有JSON里面的{}不能生成作用域。
根据作用域规则
现在,先让我们看一个例子。
console.log(a);//undefined
console.log(fn);//function fn(){}
var a=0;
function fn (){ }
第二个例子:
console.log(a)
var a=1
function fn(){
console.log(a)
var a=10;
function fn2(){
a=20;
}
fn2();
console.log(a)
}
fn()
console.log(a)
结果是: 第一个打出的是undefined。因为声明被提前。第二个是fn的console也是undefined理由同上。第三个:20,按照执行顺序来看。第四个是 1,因为fn并没有引用外部变量。这里最主要的是变量声明的提前。
让我们再看一下以下的问题。
console.log(fn);
var fn=function(){ console.log(1);};
console.log(fn);
根据等号后执行,输出的结果是undefinded,function(){console.log(1)}
根据作用域链让我们再看几个例子。
var a=0;
function fn1(){
a=10;
function fn2(){
console.log(a);
var b=2;
}
fn2();
console.log(b)
}
fn1();
console.log(a)
输出依次是:fn2:10,fn1:报错,全局的conosle:10
解析:首先执行fn2,fn2函数往fn1这个父级函数找到a,所以a=10;第二个console,fn1找不到这个变量,就往全局中寻找,全局也找不到就直接报错了。第三个console,经过fn1的折腾,此时全局的a已经变成10。