【JS基础】饭都喂到你嘴边了!作用域和作用域链的基础面试题解答

阅读: 评论:0

【JS基础】饭都喂到你嘴边了!作用域和作用域链的基础面试题解答

【JS基础】饭都喂到你嘴边了!作用域和作用域链的基础面试题解答

目录

  • 前言
  • 有哪些作用域类型
  • 作用域的访问规则
    • 补充1:var和let的作用域问题
    • 补充二:自由变量
  • 作用域链和原型链是俩个东西
  • a = 1形式的作用域与作用域链判断

前言

也没啥好说的,就拉几个关于作用域和作用域链的基础面试题出来遛遛,解答过程有误还望指出。基础知识默认掌握,刚学JS的小伙伴建议先别看,容易弄晕。


有哪些作用域类型

  • 全局作用域(window下)
  • 函数作用域(函数里头)
  • 块级作用域({}里头),这是es6后才有的。

作用域的访问规则

  • 内部的作用域只能往外一层层的访问
  • 只要是内部访问到了外部就会产生闭包(和网上说的不一样?)
  • 内部作用往外访问时,只看定义的时候,不看执行的时候

补充1:var和let的作用域问题

关于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

作用域链和原型链是俩个东西

虽然都涉及到找东西,但是作用域链是在找一个独立的变量,而原型链更像在找对象上的东西


a = 1形式的作用域与作用域链判断

例题一

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 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23