前端开发JS白板编程题目若干
在前端开发参加面试的时候,无论是校招还是社招,往往都会碰到让我们直接在白纸或者白板上手撸代码的题目。由于是手撸代码,这些题目肯定不会过于复杂和冗长,否则面试那么一小会时间根本写不完。本文总结了几个我本人在面试中碰到的小问题,暂且记录下来以供后人参考吧。
1. 实现throttle函数。
throttle函数即节流函数,在underscore和lodash这两个库中都有对应的实现。其实现的效果就是在给定的时间间隔内,函数最多只能执行1次。例如有函数A,设定其时间间隔为10s,如果在第0秒的时候已经执行了函数A,然后在第5秒的时候想要再次执行函数A的话,不会立即执行,而是等待5秒钟再执行。在第7秒的时候想要再次触发函数A,则第5秒那个函数A直接取消,第7秒这个函数A等待3秒钟后执行。这样保证了每个10秒钟的区间内,函数A只能执行1次。
var throttle = function (func, wait) {
  var timeout = null; // setTimeout的返回值
  var previous = 0; // 上次执行此函数的时间
  return function () {
    var now = new Date();
    var remaining = wait - (now - previous); // 距离设定的时间间隔还剩多少时间
    var context = this;
    var args = arguments;
    // 清除已经设定的定时器,如果timeout=null,则这下面句没有任何效果
    clearTimeout(timeout);
    // 现在距离上次执行已经超过了设定间隔,直接执行该函数
    if (remaining <= 0) {
      previous = now;
      timeout = null;
      func.apply(context, args);
      return;
    }
    // 还没到时间间隔就再次想执行,则清除之前设置的定时器,重设定时器等待一段时间后执行函数
    timeout = setTimeout(function () {
      previous = now;
      timeout = null;
      func.apply(context, args);
    }, remaining);
  };
};
2. 实现debounce函数。
debounce即防抖函数。可参考underscore或lodash库对此函数的实现。如果函数A防抖并且时间间隔为10秒,那么当想要执行函数A时,不会立即执行而是等待10秒之后再执行。如果第5秒又想要执行函数A了,那第10秒要执行的A直接被取消,而是重新开始10秒计时,也就是等到第15秒才会执行函数A。debounce常见的场景就是搜索引擎的实时搜索联想,在你向搜索框输入文字的过程中,为了避免频繁地调用后端接口,必须等待输入完成,间隔一小段时间没有新的输入时,再去调用后台接口获取搜索联想词。
var debounce = function (task, wait) {
  var timeout = null;
  return function () {
    var context = this;
    var arg = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(function () {
      task.apply(context, arg);
    }, wait);
  }
};
3. 假设目前已经有函数$ajax,主要功能是向后台发送一个请求,结果以Promise方式返回,如$ajax(option).then(successCb).catch(failCb),其中successCb和failCb分别是成功和失败时候的回调函数。请实现一个函数myAjax,返回值依然是Promise,但要求加入重试功能,该函数内部依然是使用$ajax实现,只不过在$ajax失败一次之后间隔1秒钟再重试1次,再失败再隔1秒后重试,直到重试到第5次,如果全都失败了,那myAjax所返回的Promise则reject,只要有任意一次成功,则停止重试,直接resolve。
var myAjax = (function () {
  var failCount = 0;
  return function (option) {
    return new Promise((resolve, reject) => {
      $ajax(option).then(() => {
        failCount = 0;
        resolve();
      }).catch(() => {
        failCount++;
        if (failCount >= 5) {
          failCount = 0;
          reject();
          return;
        }
        setTimeout(function () {
          myAjax(option).then(() => {
            resolve();
          }).catch(() => {
            reject();
          });
        }, 1000);
      })
    })
  }
})();
4. 实现wait函数,即延迟执行某函数,使用方法为wait(1000).then(myFunction),即等到1秒钟之后执行myFunction。
var wait = function (time) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve();
    }, time);
  })
};
5. 编写一个函数,将嵌套的数组转化成扁平的数组,例如:输入 [1, 2, 3, [4, 5, [6]], [6, 8] ],输出 [1, 2, 3, 4, 5, 6, 6, 8]。
var flatten = function (arr) {
  let result = [];
  for (let val of arr) {
    if (Array.isArray(val)) {
      result.push(...flatten(val));
    } else {
      result.push(val);
    }
  }
  return result;
}
6. 编写一个函数,输入一个字符串,将字符串中第一个只出现一次的字符返回。不存在的话返回false。
思路:如果某个字符在字符串中只出现了一次,那么该字符在字符串里面的第一次出现和最后一次出现的位置是一样的,利用String.prototype.indexOf和String.prototype.lastIndexOf求出一个字符在字符串里面第一次出现和最后一次出现的位置,判断是否相等来决定是否只出现了一次。如下:
var uniqueChar = function (str) {
  let len = str.length;
  for (let i = 0; i < len; i++){
    let chr = str[i];
    if (i === str.lastIndexOf(chr)){
      return chr;
    }
  }
  return false;
}
不过上面这个算法有个小瑕疵,就是时间复杂度是O(n^2),并不算太高效。本着用空间换时间的办法,我们可以换一种思路,先遍历一次字符串,期间以每个字符为hash的key,hash的value为该字符出现的次数。这样一次遍历下来就构建完成了一个hash表,然后再遍历一次,查看每个字符在hash表里面的value是不是1,如果是1,则停止遍历直接返回该字符。
var uniqueChar = function (str) {
  let obj = {};
  for (let i = 0; i < str.length; i++) {
    let chr = str[i];
    if (obj.hasOwnProperty(chr)) {
      obj[chr] ++;
    } else {
      obj[chr] = 1;
    }
  }
  for (let i = 0; i < str.length; i++) {
    let chr = str[i];
    if (obj[chr] === 1) {
      return chr;
    }
  }
  return false;
}
7. 随便找一个Array.prototype里面的方法,自己手动实现一下。
连接若干个数组的concat方法:
Array.prototype.concat = function () {
var result = [...this];
for (var i = 0; i < arguments.length; i++) {
if (Array.isArray(arguments[i])) {
result.push(...arguments[i]);
} else {
result.push(arguments[i]);
}
}
return result;
}
前端开发JS白板编程题目若干的更多相关文章
- 前端分享----JS异步编程+ES6箭头函数
		前端分享----JS异步编程+ES6箭头函数 ##概述Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只 ... 
- ES6 常用总结(前端开发js技术进阶提升总结)
		一.变量声明const和let 在ES6之前,我们都是用var关键字声明变量.无论声明在何处,都会被视为声明在函数的最顶部(不在函数的最顶部就在全局作用域的最顶部).这就是函数变量提升例如: 不用关心 ... 
- [JS前端开发] js/jquery控制页面动态加载数据 滑动滚动条自动加载事件
		页面滚动动态加载数据,页面下拉自动加载内容 相信很多人都见过瀑布流图片布局,那些图片是动态加载出来的,效果很好,对服务器的压力相对来说也小了很多 有手机的相信都见过这样的效果:进入qq空间,向下拉动空 ... 
- [JS前端开发] js/jquery控制页面动态载入数据 滑动滚动栏自己主动载入事件
		本人小菜鸟一仅仅.为了自我学习和交流PHP(jquery,linux,lamp,shell,javascript,server)等一系列的知识,小菜鸟创建了一个群.希望光临本博客的人能够进来交流.寻求 ... 
- Web前端开发--JS技术大梳理
		什么是JS JavaScript是一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语 ... 
- 前端开发JS——数组
		25.数组 1)声明数组: ①构造函数创建数组 var arr = new Array(); console.log(arr): //[] var arr = new Array(2 ... 
- 前端开发JS——引用类型
		10.流程控制语句 注:var obj = {}:这里的obj转换boolean语句为true if语句和java是一样的,判断条件也是根据上篇博客提到的假性值 // 弹出一个带输入框的 ... 
- 前端开发JS——快速入门
		1.JS的核心标准ECMAScript 组成 ECMAScript------>核心语法标准 DOM------------->对文档节点的操作 ... 
- 前端开发 —— js 常用工具函数(utilities)
		1. 时间 function getCurTime() { var date = new Date(); return date.toLocaleTimeString(); } date.toLoca ... 
随机推荐
- [leetcode]61. Rotate List旋转链表
			Given a linked list, rotate the list to the right by k places, where k is non-negative. Example 1: I ... 
- 1.为什么使用spring boot
			最近2年spring cloud微服务比较流行,Spring Cloud基于SpringBoot,为微服务体系开发中的架构问题提供了一整套的解决方案, 本文总结一下为什么要使用Spring boot, ... 
- Tigase 发送消息的流程源码分析
			XMPP 的<message/>节是使用基本的”push”方法来从一个地方到另一个地方得到消息.因为消息通常是不告知的,它们是一种”fire-and-forget”(发射后自寻目的)的机制 ... 
- linux内存黑洞
			1.问题 k8s集群中node节点的内存使用率居高不下,使用率达到90%多.通过以下命令可以发现此虚拟机分配的内存为15g,但是用户进程使用的内存总共为7个多g,并且slab和pageTables使用 ... 
- gooflow学习笔记
			前端jqury脚本实现流程设计,兼容目前主流浏览器 gooflow 默认属性节点只有:id,name,top,left,width,height,type (各个版本不同,属性节点有所增加),但是这些 ... 
- python 数据可视化 -- 真实数据的噪声平滑处理
			平滑数据噪声的一个简单朴素的做法是,对窗口(样本)求平均,然后仅仅绘制出给定窗口的平均值,而不是所有的数据点. import matplotlib.pyplot as plt import numpy ... 
- Go的并发调度原理
			Go语言是为并发而生的语言,Go语言是为数不多的在语言层面实现并发的语言:也正是Go语言的并发特性,吸引了全球无数的开发者. 并发(concurrency)和并行(parallellism) 并发 ... 
- mercury水星路由wifi连接不上的坑
			如题,房东发给我的水星路由,是有些bug的,比方说我的手机会偶尔某天连上了没有网络,但是其他wifi设备和有线就没问题. 这种wifi网络很差甚至没有网络的问题会随机在你的wifi设备上发生,你甚至连 ... 
- zabbix3.0监控Windows服务器
			我们下载后,解压开始有多个文件: conf目录存放是agent配置文件bin文件存放windows下32位和64位安装程序 找到conf下的配置文件 zabbix_agentd.win.conf ,修 ... 
- html中script标签的使用方法
			向HTML页面中插入JavaScript的主要方法,就是使用<script>元素.这个元素由Netscape创造并在Netscape Navigator2中首先实现.后来,这个元素被加入到 ... 
