[JavaScript面试题]两道关于变量提升、函数提升、作用域的JavaScript面试题
1、变量提升和函数提升
function b(){
console.log(a);
var a = 10;
function a(){}
a = 100;
console.log(a);
}
b(); // function(){}, 100
解析:
执行第一句console.log(a)时,同时声明了函数a和变量a,根据规则,变量a的声明被忽略,所以打印出function;
执行第二句console.log(a)时,a已经被重新赋值为100。
扩展:
函数提升和变量提升规则:
同名的变量,后声明的会被忽略,同时只有声明被提升,也就是此时变量的值是undefined;
同名的函数,后声明的会覆盖先声明的;
同名的函数和变量,变量声明被忽略
2、变量作用域和上下文
var num = 10;
var obj = {
num: 8,
inner: {
num: 6,
print: function(){
console.log("num: " + num + ", this.num: " + this.num);
}
}
}
num = 888;
下面语句输出什么?
1、obj.inner.print();
2、var fn = obj.inner.print;
fn();
3、(obj.inner.print)();
4、(obj.inner.print = obj.inner.print)();
解析:
1、888, 6
首先根据[作用域链]查找num。在print函数中没有定义num,就会向上一级查找,此时的作用域链只有两层:顶层的window和print,所以就会找到全局变量num,也就是window.num,此时num等于888。
其次查找this.num。此时this指向obj.inner,obj.inner.num = 6。
2、888, 888
在JavaScript中,函数是是引用类型,所以此语句相当于让fn指向obj.inner.print的地址。此时调用fn是在window下,所以输出两次888。
3、888, 6
4、888, 888
()是表达式,(obj.inner.print)等于obj.inner.print,这和第四问中不同,第4问括号中存在一个赋值语句,赋值语句有返回值,等于等号右侧的计算结果。在这里,这个返回值是obj.inner.print的地址,相当于在当前window环境中调用这个地址的函数,所以情况就变得和第2问一样了。
评论已关闭