今天给大家介绍几道奇葩的JavaScript面试题。

1、如何交换变量

面试题:如何不借助第三个变量交换上面两个值? 语言不限

实现方法如下:

let a = 3;
let b = 5;
console.log("原始值: ", a, b);  // 原始值:  3 5

// 面试题: 如何不借助第三个变量交换上面两个值? 语言不限

// 方法1: 简单的数学逻辑
(function (){
  a = a + b;
  b = a - b;
  a = a - b;
  console.log(a, b)  // 5 3
})();

// 方法2: 异或
(function (){
  a = a ^ b;
  b = a ^ b;
  a = a ^ b;
  console.log(a, b)  // 3 5
})();

// 注意: 方法1和方法2只能用于交换number

// 方法3: ES6特性 结构赋值 => number、string、object
(function (){
  [a, b] = [b, a]
  console.log(a, b)  // 5 3
})();

以上的方法1、2每种编程语言都通用(数学原理),方法3部分编程语言可行

2、如何随机生成整数

面试题:输入n(1<=n<=9),输出一个n位的随机数(输出格式不限,可以输出整数或整数形式的字符串)

下面是用JavaScript写的一个比较特殊的写法(其他语言不一定可行):

let generateRandomNum = function(n){
  // 随机生成一个n位字符串(每位可能是0到9中的任意一个数)
  let res = Math.random().toString().slice(2, 2 + n);
  // 处理第一位是0的情况
  return res[0] === '0' ? "1" + res.slice(1) : res;
}

// test: 每一种情况测试5次  一共测试45次
for(let i=1; i<=9; i++){
  for(let j=1; j<=5; j++){
    console.log(generateRandomNum(i))
  }
}

3、内存循环break外层循环

面试题:一个两层循环 如何在最内层的循环里面break掉最外层的循环

// 以下的break只能结束掉最内层的循环 而不能结束最外层循环
console.log("break演示:")
for (let i = 1; i <= 5; i++) {
  for (let j = 1; j <= 3; j++) {
    if (i === j) {
      console.log(i, j)
      break;
    }
  }
}
/* 以上代码的输出如下:
break演示: 
1 1 
2 2
3 3
*/

// 以下的break通过比较复杂的方式实现了结束最外层循环
console.log("break无脑方法:")
let flag = false;
for (let i = 1; i <= 5; i++) {
  for (let j = 1; j <= 3; j++) {
    if (i === j) {
      console.log(i, j)
      flag = true;
      break;
    }
  }
  if(flag){
    break;
  }
}
/* 以上代码的输出如下:
break无脑方法: 
1 1 
2 2
3 3
*/

// 以下的break使用label实现了结束最外层循环
console.log("break-label:")
outerLoop: for (let i = 1; i <= 5; i++) {
  for (let j = 1; j <= 3; j++) {
    if (i === j) {
      console.log(i, j)
      break outerLoop;
    }
  }
}
/* 以上代码的输出如下:
break-label: 
1 1 
2 2
3 3
*/

注意:label的方式不是每一种编程语言都支持