也没啥好说的,就拉几个关于作用域和作用域链的基础面试题出来遛遛,解答过程有误还望指出。基础知识默认掌握,刚学JS的小伙伴建议先别看,容易弄晕。
window
下){}
里头),这是es6后才有的。关于var
var是函数级的作用域,还涉及到了变量提升。
var name = 'hello';
(function(){if(typeof name ==='undefined'){var name = 'jack';console.log("true"+name);}else{console.log('false'+name);}
})()
// 问:控制台打出啥?
// 解答var name = 'hello';
(function(){var name // undefinedif(typeof name ==='undefined'){ // truevar name = 'jack'; // var声明的变量是函数级作用域,变量提升到外部console.log("true"+name);}else{console.log('false'+name);}
})()
var bar = 1;
function test(){console.log(bar);//undefined 因为变量提升var bar = 2;console.log(bar);//现在函数内部找局部变量 2
}
test()
关于let
是块级作用域
function demo(){let n=2;if(true){let n =1;}console.log(n); //输出几? 如果改成var就是输出啥
}
demo(); // 2
具体可以看【es6入门】变量声明
通过作用域链获取到的变量可以被叫做自由变量
其实就是遵循上面说的作用域的访问规则的第三条。自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方!
自由变量的题一般都喜欢结合闭包来考察。咱们来举例(例子来源于慕课网):
// 函数作为返回值
function create() {const a = 100return function () {console.log(a)}
}const fn = create()
const a = 200
fn() // 100// 函数作为参数被传递
function print(fn) {const a = 200fn()
}
const a = 100
function fn() {console.log(a)
}
print(fn) // 100
虽然都涉及到找东西,但是作用域链是在找一个独立的变量,而原型链更像在找对象上的东西
例题一
function test(){console.log(bar);//因为作用域链,在局部中没有变量声明,js不知道bar是什么,直接报错bar = 2 // js执行到这才能认识bar
}
test()
例题二
var f = true;
if(f===true){var a = 10;
}
function fn(){var b = 20;c=30; // 这种没有声明的形式没有变量提升机制,js执行到了才认得// 注意如果 var b = c =20 ,c也是个全局变量
}
fn();
console.log(a,c) // c是全局变量
console.log(b) // b是var声明的变量,为函数级作用域,所以报错
例题三
function fn() {var a = 10window.a = 20console.log(a)//因为作用域链,先找本层的变量,再找外部的,虽然window.a是在本层的,但是它是一个全局变量所以是找的是本层的变量a = 10
}
例题四
function fn() {var a = 10window.a = 20a = 30 //作用域链关系,先找局部变量,找到,修改值console.log(this.a) //而这里打印的是全局变量 20
}
例题五
load = function fn() {window.a = 20a = 30 //因为作用域链,先找内部的变量,没有局部变量,有个全局window.a的,那就修改全局的console.log(a) //局部变量没有,打印全局的 30
}
例题六
function fn() {window.a = 20a = 30 //因为作用域链,先找内部的变量,没有局部变量,有个全局window.a的,那就修改全局的console.log(this.a) //此时this指window 30
}
例题七
function fn() {window.a = 20a = 30 // 下面有局部变量的声明,变量提升,所以a=30 改的是局部的var aconsole.log(this.a) //20
}
例题八
var a = 10
function fn(a) {alert(a)a = 20 // 此时改的是参数a的值,不是修改全局变量
}
fn(30) //弹出30
alert(a) //弹出10
例题九
var a = 10
function fn() {alert(a)a = 20
}
fn() //因为作用域链,函数内找不到变量声明,只能向函数外找,弹出10
alert(a) //此时外部的a变量已经和函数内部关联了(也就是作用域链),所以a的赋值生效,弹出20;
未完待续~
本文发布于:2024-01-29 17:01:47,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170651891116864.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |