以下代码有点不明白
function a(){
var tag=true;
b();
}
function b(){
console.log(tag)
}
a();
执行a函数,那么就是先声明tag=true,然后执行b,按照把b中的console.log(tag)这句语句搬进a中替代b()的话,那么tag应该是可以打印出的,为什么tag为undefine?我知道可以通过传参解决,但是一直说不清楚其中机制,求大牛解答。
以下代码有点不明白
function a(){
var tag=true;
b();
}
function b(){
console.log(tag)
}
a();
执行a函数,那么就是先声明tag=true,然后执行b,按照把b中的console.log(tag)这句语句搬进a中替代b()的话,那么tag应该是可以打印出的,为什么tag为undefine?我知道可以通过传参解决,但是一直说不清楚其中机制,求大牛解答。
js
是词法作用域(除了this
),也就是说,函数的作用域是在函数定义好时就已经确定好了。a
函数是一个独立的作用域,有着自己的变量对象,b
函数是一个独立的作用域,有着自己的变量对象,这两个作用域是平级的,其作用域链的上层为全局作用域。题主要是想让b
函数能放到a
内定义的tag
变量的话,需要改变定义的方式,也就是将b
函数内定义在a
函数内,这样b
的作用域链会包含a
的作用域。
这是this的指向问题。
在函数里面,this的指向是window。
在a里面调用b,b的this此时指向window,没有tag这变量,输出就是undefined了
搜了下相关文章:http://web.jobbole.com/85198/
function a(){
var tag=true;//此处申明的只是局部变量,而非window.tag
b();//此处执行b的内容
}
function b(){
console.log(tag) //tag相当于window.tag,
}
a()//所以执行结果是undefined
//--------我们不妨把程序修改一下
var tag = 'b' //申明了window.tag变量
function a(){
var tag='a';//此处申明的只是局部变量,而非window.tag
b();//此处执行b的内容
}
function b(){
console.log(tag) //tag相当于window.tag,
}
a()//所以执行结果就是'b'
因为函数的作用域链式在函数声明的时候就定义好的,而不是在函数调用的时候。虽然b是在a中调用的,而console.log(tag)这个函数是在b中执行的,它会在b中寻找变量tag,找不到就会到b的上一级作用域,也就是全局中寻找tag(因为b是在全局中声明的),还找不到就返回undefined。
如果把b声明在a中,就可以找到tag了,即:
function a() {
var tag = true;
b();
function b() {
console.log(tag);
};
};
a();
@Lapsec 链接中的文章说this指向的作用域是在调用时确定,但实际测试结果显示貌似不是这样
var
func = function(){
console.log(this);
},
scop = {
'a':function(){
func();
console.log(this);
}
};
scop.a();
func是在全局作用域下定义,调用是在scop.a中。但输出的结果是指向了window.
scop.a定义在scop中,调用是在全局作用域下调用,但输出的结果是指向scop,而非window.
所以this指向是在定义时决定的。
你这段代码运行出来的结果应该是报错才对。
如果你在函数外声明了var tag;才会输出tag is undefined。
说简单点,这就是个作用域的问题。
你在a函数体内声明了tag变量,b函数体内是访问不到的。
说复杂点,还需要扯到scope和lexical上。
10 回答11.2k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
ES6之前,Js中只有函数是具有块级作用域的,所以a中使用var声明的tag是在函数a作用域内的,而函数b执行时会在自己的作用域中找tag,找不到就会去外层找,直到全局对象上还没有就是
undefined
,这里a和b不是包含关系,因此b自身没有tag时不会去a中找,而是去全局找,结果也没有,所以是undefined
,如果你的b函数声明是在a内部的,你再调用就会打印出true了。