前端笔试面试题总结(三)

  1. console.log 里面需要添加什么可以打印出注释的值?可以从下列选项中找出正确的那一项
function* startGame () {
   const answer = yield "Do you love JavaScript?";
   if(answer !== "Yes"){
      return "Oh wow... Guess we're gone here";
   }
   return "JavaScript loves you back";
}
const game = startGame();
console.log(/* 1 */);  // - Do you love JavaScript?
console.log(/* 2 */);  // - JavaScript loves you back

A. game.next("Yes").value and game.next().value
B. game.next.value("Yes") and game.next.value()
C. game.next().value and game.next("Yes").value
D. game.next.value() and game.next.value("Yes")

解析:
yield关键字本身没有返回值,或者说总是返回undefined。next()方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
上面代码第一次若要返回Do you love JavaScript?,调用next()方法不带参数,返回yield的表达式的值Do you love JavaScript?,第二次调用next("Yes")方法携带参数,将上一次的yield的表达式的值设为"Yes",因此answer等于"Yes",返回JavaScript loves you back

  • 注意:由于next()方法的参数表示上一个yield表达式的返回值,所以在第一次使用next()方法时,传递参数是无效的。V8 引擎直接忽略第一次使用next()方法时的参数,只有从第二次使用next()方法开始,参数才是有效的。从语义上讲,第一个next()方法用来启动遍历器对象,所以不用带有参数。

正确答案:C

  1. 从以下选项中找出正确的打印值
// index.js
console.log('running index.js');
import { sum } from './sum.js';
console.log(sum(1,2));
// sum.js
console.log('running sum.js');
export const sum = (a,b) => a + b;

A. running index.js,running sum.js,3
B. running sum.js,running index.js,3
C. running sum.js,3,running index.js
D. running index.js,undefined,running sum.js

解析:

// index.js
console.log('running index.js');  // - 编译阶段执行后才执行
import { sum } from './sum.js';   // - 编译阶段就执行,先于js代码执行
console.log(sum(1,2));  // - 依次执行 3
// sum.js
console.log('running sum.js'); // - 先打印
export const sum = (a,b) => a + b;

正确答案:B

  1. 从以下选项中找出正确的打印值(使用哪个构造函数可以成功继承Dog类?)
class Dog {
    constructor(name) {
      this.name = name;
    }
};
class Labrador extends Dog {
    // 1
    constructor(name,size) {
        this.size = size;
    } 
    // 2
    constructor(name,size) {
        super(name);
        this.size = size;
    }
    // 3
    constructor(size) { 
        super(name);
        this.size = size;
    }
    // 4
    constructor(name,size) {
        this.name = name;
        this.size = size;
    }
};

A. 1
B. 2
C. 3
D. 4

解析:Labrador是继承了Dog类的派生类,派生类的构造函数必须包含super调用,访问派生类的构造函数中的'this'前,必须调用'super'

正确答案:B

  1. 从以下选项中找出正确的打印值
const one = (false || {} || null)
const two = (null || false || "")
const three = ([] || 0 || true)
console.log(one,two,three);

A. false null [ ]
B. null "" true
C. { } "" [ ]
D. null null true

解析:

// - 短路运算符
const one = (false || {} || null)   // - 任何一个对象转换为布尔值都是真值 {}
const two = (null || false || "")  // - null、undefined、""转换为布尔值都是false,所以值为最后一个  ""
const three = ([] || 0 || true)  // -数组也是对象, []转换为布尔值为真值  []
console.log(one,two,three);  // - {}, "", [] 

正确答案:C

  1. 用代码方式实现数组非零非负最小值index获取
const arr = [10,21,0,-7,35,7,9,23,18];

答案:

const arr = [10,21,0,-7,35,7,9,23,18];
const getIndex = arr => {
   let index = -1;
   const minVal = arr.reduce((prev,cur) => {  // - prev上一轮的结果,cur当前的
      return (prev<= 0 || cur <= 0) ? Math.max(prev,cur) : prev> cur? cur: prev;  // - 排除掉0和负数
   },-1);  // - 起始值 -1
   console.log(minVal);
   index = arr.findIndex(item => item === minVal);
   return index;
}
console.log(getIndex(arr));

解析:
(1). JS中的reduce方法:

  • 语法:array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
    reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
  • 参数:
    previousValue 必需。初始值, 或者计算结束后的返回值。
    currentValue 必需。当前元素
    currentIndex 可选。当前元素的索引
    arr 可选。当前元素所属的数组对象。
    initialValue 可选。传递给函数的初始值
    这个例子index是从-1开始的,第一次的prev的值是我们设置的初始值-1,数组长度是9,reduce函数循环9次。

(2). findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置。
findIndex() 方法为数组中的每个元素都调用一次函数执行:

  • 当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数。
  • 如果没有符合条件的元素返回 -1
  1. 输出以下代码运行结果,并解释原因?如果希望每隔1s输出一个结果应该如何改造?注意不可改动square方法
const list = [1,2,3];
const square = num => {
   return new Promise({resolve,reject} => {
      setTimeout(() => {
          resolve(num * num);
      },1000)
    })
}
function test () {
  list.forEach(async x => {   
      const res = await square(x)
      console.log(res);
   })
}
test();

解析:

const list = [1,2,3];
const square = num => {
   return new Promise({resolve,reject} => {
      setTimeout(() => {
          resolve(num * num);
      },1000)
    })
}
//function test () {
//  list.forEach(async x => {   // - forEach是并行执行的  
//      const res = await square(x)
//      console.log(res); // - 1 4 9
//   })
//}
async function test () {
// - 方法1
  for(let i = 0;i < list.length; i++){
      const res = await square(list[i])
      console.log(res);
   }
// - 方法2
  for(let x of list){
      const res = await square(x);
      console.log(res);
   }
}
test();

答案:1,4,9

  1. 实现Promise.retry,成功后resolve结果,失败后重试尝试超过一定次数才真正的reject

答案:

Promise.retry = async (fn,times) => {
  while(times > 0){
    try{
      const res = await fn();  // -resolve
      console.log(res);
    } catch(error){
        console.log('try again...');
        times--;
    }
  }
}
const test = () => {
  return new Promise((resolve,reject) => {
    const num = Math.floor(Math.random() * 10);
    if(num > 7){
      resolve(num);
    } else {
      reject(new Error(num));
    }
  })
}

Promise.retry(test,5); // - 超过5次reject
  1. 说出下列代码的输出结果,并解释原因
var a;
console.log(typeof a);
console.log(b);
b = 10;
console.log(typeof b);

答案:

var a;   // - 声明未赋值 
console.log(typeof a);   // - 'undefined'
//console.log(b);        // - reference Error
b = 10;     // - 未声明直接赋值
console.log(typeof b);   // - 'number'

注:typeof返回的都是string类型

  1. 输出今天的日期,以YYYY-MM-DD的方式

答案:

const date = new Date();
const year = date.getFullYear();  // -2021
const month = date.getMonth() + 1; // - 1月对应的是0 这个数字
const day = date.getDate();
console.log(`${year}-${fill0(month)}-${fill0(day)}`);
const fill0 = num => num < 10 ? '0' + num : num;    // - 补位

注:ES6中的${}新语法,这是ES6中新增的字符串方法,配合反单引号完成拼接字符串的功能。

  1. 用JS实现随机选取10-100之间的10个数字存入一个数组,并排序

答案:

const arr = [];
const getRandom = (start,end) => {
  return Math.floor(Math.random() * (end -start + 1) + start);
}
for(let i = 0; i < 10;  i++){
  arr.push(getRandom(10,100));
}
arr.sort((a,b) => a - b);  // - 排序
console.log(arr);

注:

  • Math.floor()为向下取整
  • array.sort(compareFunction)
    compareFunction 可选。定义替代排序顺序的函数。该函数应返回负值、零值或正值,具体取决于参数,例如:function(a, b){return a-b}
    sort() 方法比较两个值时,将值发送给比较函数,根据返回的(负、零、正)值对值进行排序。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容