javaScript基础面试题 --- JS作用域

面试10家公司,得有8家会问到作用域的题。所以说JS的作用域一定要弄清楚,非常重要!

1、除了函数之外,JS没有块级作用域
2、作用域链:内部可以访问外部的变量,但是外部不能访问内部变量,如果内部有,优先内部的,如果内部没有,就先查找外部的
3、注意声明变量是用var,还是没有写,如果没写var,直接赋值,就是(window.下面的全局)
4、变量提升
5、优先级:声明变量 > 普通声明函数 > 参数 > 变量提升
普通声明函数,不看写函数的时候的顺序,反正都是要变量提升的,而且取值就是函数本身,这就相当于是,函数不仅声明提升了,定义也提升了


题目:除了函数之外,JS没有块级作用域

结果为:报错
分析:
因为a在函数内部,函数有块级作用域
但是在函数外部,a不仅没声明也没定义
注意:如果没声明没定义就报错,如果声明了,没定义,就是undefined

在这里插入图片描述


结果为:10
分析:
因为JS除了函数以外没有块级作用域
for循环没有块级作用域 i做完循环=10
所以最后打印出来为10

在这里插入图片描述


结果为: 10
分析:
因为JS除了函数以外没有块级作用域
a = 10

在这里插入图片描述


考点:作用域链 – 内部可以访问外部的变量,但是外部不能访问内部变量

结果为:10
分析:
foo内部没有a
根据作用域链,一层一层往外找

在这里插入图片描述


考点:使用了var,就是声明了变量,没使用var的,就是没声明变量

结果:
·a不能打印,会报错,因为a在函数内部声明,具有块级作用域,函数外部没有定义

·b可以打印,结果为10,因为b没有使用var在函数内部声明,b相当于是全局变量windows.b=10相当于是在函数外面声明赋值的

在这里插入图片描述


结果为:
undefined
undefined

分析:
js除了函数,没有块级作用域,所以if不是块级作用域
var a变量提升 所以第一个a是undefined
由于if语句里面是false,所以并没有赋值 第二个a也是undefined

在这里插入图片描述


考点:变量提升

结果:
函数内部的bar变量提升却没有赋值,所以第一个是undefined
第二个赋值了,就是2

在这里插入图片描述


优先级:

结果:10
分析:
声明变量 > 普通声明函数

在这里插入图片描述


结果:f(){}
函数表达式声明,就是a的变量声明

在这里插入图片描述


结果:f(){}
分析:
虽然函数定义在下方,但是打印出来的不是undefined
因为,普通函数声明 取 函数值,不取声明值
这意味着:在普通声明函数上方调用,或者在普通声明函数下方调用,这个顺序是没影响的

在这里插入图片描述


考点:声明变量 > 普通声明函数 > 参数 > 变量提升

结果:100
分析: 参数 > 变量提升
在这里插入图片描述


声明变量 > 普通声明函数 > 参数 > 变量提升

结果为:10
分析:声明变量 > 普通声明函数 > 参数 > 变量提升

在这里插入图片描述


注意:这里的a是windows下的,其实a不在函数块级作用域内,它其实是windows.a,在函数外部找到的

在这里插入图片描述


结果为:20
分析:a其实是windows下的,但是本作用域中有var a = 20,所以最后是20


结果为:10
分析:这是上面题反过来,这是变量的再赋值了,所以是10

在这里插入图片描述


这个也是变量的再次赋值

结果:10
分析:
首先是var a变量提升
然后,a = 10,变量的赋值

在这里插入图片描述

2、普通函数声明、函数表达式、箭头函数有什么区别?

在 JavaScript 中,普通函数声明、函数表达式、和箭头函数在语法和行为上有一些区别。下面是主要的区别:

1. 普通函数声明(Function Declaration)

普通函数声明在其作用域内会被提升(hoisted)。

foo(); // 可以调用,因为函数提升
function foo() {
  console.log('普通函数声明');
}
  • 拥有自己的 thisargumentssupernew.target
  • 可以使用 new 运算符调用(即作为构造函数)。
  • 可以被提升。

2. 函数表达式(Function Expression)

函数表达式定义了一个匿名函数,或者可以命名,但是不会被提升。

foo(); // TypeError: foo is not a function

var foo = function() {
  console.log('函数表达式');
}
  • 与普通函数声明相似,拥有自己的 thisargumentssupernew.target
  • 可以使用 new 运算符调用(即作为构造函数)。
  • 不会被提升。

3. 箭头函数(Arrow Function)

箭头函数使用 “箭头” (=>) 语法编写。

const foo = () => {
  console.log('箭头函数');
}
  • 没有自己的 thisthis 的值继承自包围它的函数(词法 this)。这使得箭头函数在某些场景中更为方便,比如在回调函数中。
  • 没有 arguments 对象。如果你需要访问参数列表,你需要使用剩余参数(...args)。
  • 不能使用 new 运算符调用。箭头函数没有 [[Construct]] 方法,因此不能作为构造函数。
  • 没有 supernew.target

总结:

  • 普通函数声明可以被提升,而函数表达式和箭头函数不能。
  • 箭头函数不绑定自己的 this,并且缺少普通函数和函数表达式的一些特性,如 arguments 对象。
  • 普通函数声明和函数表达式在功能上相似,但函数表达式不会被提升。
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值