分析几道经典但依然超难做的前端面试题

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 分析几道经典但依然超难做的前端面试题,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

1. a 应该等于什么可以让下面的 console.log 输出 true?

const a = void 0;

console.log(a == 1 && a == 2 && a == 3);// true

2. 实现 sum 函数,参数为数组,求该数组所有项之和,不允许使用循环和数组方法

const arr = [1, 2, 3, 4, 5]

function sum (arr) {
	// TODO:
}

sum(arr);// 15

3.请说出如下代码的输出

var x;
let y;
var z;

if(true) {
  let z;
  x();
  console.log(z);
  x = 1;
  function x(z) {
    z = 4;
  }
  function y(z) {
    z = 3;
  }
  z = () => {}
  y(z);
  console.log(z);
  x = 2;
  console.log(x);
}

console.log(x);
console.log(y);
console.log(z);

题解

1

这一题是在考察隐式类型转换。

当两个类型不一样的变量进行双等于比较时,会调用它的 valueOf 方法,并使用 valueOf 方法返回的值进行比较。

我们只需要定义一个初始为 1 的属性,每次调用时让它增加 1 就可以了。

var a = {
	n: 1,
  valueOf() {
    return this.n++;
  }
}

2

这一题是在考察递归。
遍历一个数组中的所有子项,能用到的方法只有循环和递归。
首选需要分析递归公式。
假设有个内部函数 _sum,该函数接受 i 作为参数,可以计算出从数组第 i 位到数组末尾之和。
基于这个函数,我们还可以推演出一个递推公式:_sum(i) = arr[i] + _sum(i + 1)。
最后再来分析边缘情况,当参数 i 大于等于数组的 length 之后,就无法求和了,所以这时返回 0。

function sum(arr) {
  function _sum(i) {
    if(i >= arr.length) return 0
    return arr[i] + _sum(++i)
  }
	return _sum(0)
}

3

这一题是在考察作用域。

但是题出得确实有点丧心病狂。

第 8 行输出 undefined。这个比较简单,因为调用 x 时没有传递参数,所以 x 函数中改变的 z 是 x 的参数,和外层的 z 无关。

第 18 行输出 ()=>{}。因为 15 行将 z 设置成了箭头函数,16 行调用了 y,但是在 y 中修改的是函数作用域内的参数,而不是外层的 z。

第 20 行输出 2,毫无疑问。

第 23 行输出 1,这就有点难以理解了。第 9 行代码会把外层的 x 设置为 1,但是第 10 行代码会在 if 块级作用域中创建一个函数 x。在此之后 x 的访问,都是在访问块级作用域中的 x,和外部的 x 无关。

第 24 行输出 undefined,因为外层的 y 是通过 let 声明,会形成块级作用域,if 中的函数 y 不会提升。

第 25 行输出 undefined,因为 if 块中有使用 let 声明 z,所以 z 存在块级作用域,不会起到变量提升的效果。

说实话这些题目看上去头很刁难人,但确实又是在考察基础的编程语言能力。不乏一些老手程序员也在这些「初级面试题」上面翻了跟头。

你答对了几道题呢?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137373.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!