前端常见面试题:输出结果类问题

1. 下面代码的输出是什么?

function sayHi() {
  console.log(name);
  console.log(age);
  var name = "Lydia";
  let age = 21;
}

sayHi();
复制代码
  • A: Lydiaundefined
  • B: LydiaReferenceError
  • C: ReferenceError21
  • D: undefinedReferenceError

答案

答案: D

在函数中,我们首先使用var关键字声明了name变量。 这意味着变量在创建阶段会被提升(JavaScript会在创建变量创建阶段为其分配内存空间),默认值为undefined,直到我们实际执行到使用该变量的行。 我们还没有为name变量赋值,所以它仍然保持undefined的值。

使用let关键字(和const)声明的变量也会存在变量提升,但与var不同,初始化没有被提升。 在我们声明(初始化)它们之前,它们是不可访问的。 这被称为“暂时死区”。 当我们在声明变量之前尝试访问变量时,JavaScript会抛出一个ReferenceError

译者注:

关于let的是否存在变量提升,我们何以用下面的例子来验证:

let name = 'ConardLi'
{
  console.log(name) // Uncaught ReferenceError: name is not defined
  let name = 'code秘密花园'
}
复制代码

let变量如果不存在变量提升,console.log(name)就会输出ConardLi,结果却抛出了ReferenceError,那么这很好的说明了,let也存在变量提升,但是它存在一个“暂时死区”,在变量未初始化或赋值前不允许访问。

变量的赋值可以分为三个阶段:

  • 创建变量,在内存中开辟空间
  • 初始化变量,将变量初始化为undefined
  • 真正赋值

关于letvarfunction

  • let 的「创建」过程被提升了,但是初始化没有提升。
  • var 的「创建」和「初始化」都被提升了。
  • function 的「创建」「初始化」和「赋值」都被提升了。


2. 下面代码的输出是什么?

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}
复制代码
  • A: 0 1 2 and 0 1 2
  • B: 0 1 2 and 3 3 3
  • C: 3 3 3 and 0 1 2

答案

答案: C

由于JavaScript中的事件执行机制,setTimeout函数真正被执行时,循环已经走完。 由于第一个循环中的变量i是使用var关键字声明的,因此该值是全局的。 在循环期间,我们每次使用一元运算符++都会将i的值增加1。 因此在第一个例子中,当调用setTimeout函数时,i已经被赋值为3

在第二个循环中,使用let关键字声明变量i:使用let(和const)关键字声明的变量是具有块作用域的(块是{}之间的任何东西)。 在每次迭代期间,i将被创建为一个新值,并且每个值都会存在于循环内的块级作用域。


3. 下面代码的输出是什么?

const shape = {
  radius: 10,
  diameter() {
    return this.radius * 2;
  },
  perimeter: () => 2 * Math.PI * this.radius
};

shape.diameter();
shape.perimeter();
复制代码
  • A: 20 and 62.83185307179586
  • B: 20 and NaN
  • C: 20 and 63
  • D: NaN and 63

答案

答案: B

请注意,diameter是普通函数,而perimeter是箭头函数。

对于箭头函数,this关键字指向是它所在上下文(定义时的位置)的环境,与普通函数不同! 这意味着当我们调用perimeter时,它不是指向shape对象,而是指其定义时的环境(window)。没有值radius属性,返回undefined


4. 下面代码的输出是什么?

+true;
!"Lydia";
复制代码
  • A: 1 and false
  • B: false and NaN
  • C: false and false

答案

答案: A

一元加号会尝试将boolean类型转换为数字类型。 true被转换为1false被转换为0

字符串'Lydia'是一个真值。 我们实际上要问的是“这个真值是假的吗?”。 这会返回false


5. 哪个选项是不正确的?

const bird = {
  size: "small"
};

const mouse = {
  name: "Mickey",
  small: true
};
复制代码
  • A: mouse.bird.size
  • B: mouse[bird.size]
  • C: mouse[bird["size"]]
  • D: All of them are valid

答案

答案: A

JavaScript中,所有对象键都是字符串(除了Symbol)。尽管有时我们可能不会给定字符串类型,但它们总是被转换为字符串。

JavaScript解释语句。当我们使用方括号表示法时,它会看到第一个左括号[,然后继续,直到找到右括号]。只有在那个时候,它才会对这个语句求值。

mouse [bird.size]:首先它会对bird.size求值,得到smallmouse [“small”]返回true

但是,使用点表示法,这不会发生。 mouse没有名为bird的键,这意味着mouse.birdundefined。 然后,我们使用点符号来询问sizemouse.bird.size。 由于mouse.birdundefined,我们实际上是在询问undefined.size。 这是无效的,并将抛出Cannot read property "size" of undefined



 

资料:

[译] 送你 43 道 JavaScript 面试题 - 掘金这两天的GitHub Trending repositories被一个名叫 javascript-questions的项目霸榜了,项目中记录了一些JavaScript题目。 我大概从头到尾看了一遍,都是一些基础的题目,我大概花了半个小时(有些题很简单,可以一扫而过)把这些题做完…https://juejin.cn/post/6844903869378461710

 「2021」高频前端面试题汇总之代码输出结果篇 - 掘金在前端面试中,常考的代码输出问题主要涉及到以下知识点:异步编程、事件循环、this指向、作用域、变量提升、闭包、原型、继承等https://juejin.cn/post/6959043611161952269

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南北极之间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值