前端部分面试题汇总

安全类型检测
/** 对象类型的安全检测 */
const detectionFun = {
  /** 检测数组 */
  isArray: value => {
    return Object.prototype.toString.call(value) === "[object Array]";
  },
  /**  检测函数 */
  isFunction: value => {
    return Object.prototype.toString.call(value) === "[object Function]";
  },
  /** 检测正则表达式 */
  isRegExp: value => {
    return Object.pro;
  }
};
常用浏览器事件
var EventUtil = {
// 事件监听(添加事件)
addHandler: function(element, type, handler){
    if (element.addEventListener){
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent){
      element.attachEvent("on" + type, handler);
    } else {
      element["on" + type] = handler;
    }
  },
// 事件监听(移除事件)
  removeHandler: function(element, type, handler){
    if (element.removeEventListener){
      element.removeEventListener(type, handler, false);
    } else if (element.detachEvent){
      element.detachEvent("on" + type, handler);
    } else {
      element["on" + type] = null;
    }
  }
  // 获取事件对象
  getEvent: function (event) {
    return event ? event : window.event;
  },
  // 获取目标对象
  getTarget: function (event) {
    return event.target || event.srcElement;
  },
  // 组织默认事件
  preventDefault: function (event) {
    if (event.preventDefault) {
      event.preventDefault();
    } else {
      event.returnValue = false;
    }
  },
  // 阻止冒泡
  stopPropagation: function (event) {
    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true;
    }
  }//  获取键码
getCharCode: function(event){
  if (typeof event.charCode == "number"){
    return event.charCode;
  } else {
    return event.keyCode; // IE8及之前版本
  }0
},
   // 滚轮事件  非常流行,而且所有浏览器都支持它,所以 HTML 5 也加
入了该事件 )
getWheelDelta: function(event){
  if (event.wheelDelta){
    return (client.engine.opera && client.engine.opera < 9.5 ?
        -event.wheelDelta : event.wheelDelta);
  } else {
    return -event.detail * 40;
  }
},
// 跨浏览器取得相关元素(鼠标当前进入的元素)
getRelatedTarget: function(event){
  if (event.relatedTarget){
    return event.relatedTarget;
  } else if (event.toElement){
    return event.toElement;    // IE9+
  } else if (event.fromElement){
    return event.fromElement;  // IE8
  } else {
    return null;
  }
},
}
原生js封装一个事件代理
eg: proxy(document.querySelector('ul'), 'li', 'click', function () { console.log(this.innerHTML) })
// 面向对象的编程小小的秀一下
const proxyUtil = {
  // 获取目标对象
  getTarget: function (event) {
    return event.target || event.srcElement;
  },
  proxy: function (element, targetEle, handleType, handle) {
    let _that = this
    element["on" + handleType] = function (e) {
      let target = _that.getTarget(e); // 获取目标节点
      if (target.nodeName.toLocaleLowerCase() === targetEle) {
        handle.call(target, null)
      }
    }
  }
}

proxyUtil.proxy(document.querySelector('ul'), 'li', 'click', function () {
  console.log(this.innerHTML)
})
数组转对象
 const templateData = ["codeZh", "codeCn", "taobao.cn", "taobao.com"];
 const targetReslt = { code: { Zh: "codeZh", Cn: "codeCn" }, taobao: { ".cn": "taobao.cn", ".com": "taobao.com" } };

 let arr = ["codeZh", "codeCn", "taobao.cn", "taobao.com"];

 // 先将一元数组变成二元数组
 // eg: [ ["code", "Zh"], ["code", "Cn"], ["taobao", ".cn"], ["taobao", ".com"] ]
  let arrSplit = arr.map(item => {
    if (item.indexOf(".") !== -1) {
      return item.replace(/(\.)/g, ",$1").split(",");
    } else {
      return item.replace(/([A-Z])+/g, ",$1").split(",");
    }
  });

  let obj = {};
  arrSplit.map(item => {
    if (!(Array.isArray(item) && obj[item[0]])) {
      obj[item[0]] = {};
    }
    obj[item[0]][item[1]] = item.join("");
  });
  console.log(obj);
瓶盖与酒的问题
/**  条件:三个空酒瓶还一瓶酒,5个瓶盖换一瓶酒,酒 5 元一瓶,共100元 */
function buyWine({ x = 20, y = 20, n = 20 } = {}) {
  if (x - 3 < 0 && y - 5 < 0) {
    console.log("------亲,您一共可以买" + n + "瓶酒哦--------");
  } else {
    var _x = x,
      _y = y;
    n = n + (x - (x % 3)) / 3 + (y - (y % 5)) / 5;
    y = (_x - (_x % 3)) / 3 + (y - (y % 5)) / 5 + (y % 5);
    x = (_y - (_y % 5)) / 5 + (x - (x % 3)) / 3 + (x % 3);
    console.log("每一次兑换后,空酒瓶个数:" + x, "瓶盖个数:" + y, "总数为:" + n);
    arguments.callee({ x, y, n }) // buyWine({ x, y, n })
  }
}
function init(totalMoney) {
  let x = (totalMoney - totalMoney % 5) / 5,
    y = (totalMoney - totalMoney % 5) / 5,
    n = (totalMoney - totalMoney % 5) / 5;
  return { x, y, n };
}
buyWine(init(100));
数组排序
// 冒泡排序
  bubbleSort: arr => {
    for (var i = 0, len = arr.length; i < len; i++) {
      for (var j = i + 1; j < arr.length; j++) {
        if (arr[i] < arr[j]) {
          [arr[j], arr[i]] = [arr[i], arr[j]];
        }
      }
    }
    return arr;
  },
  
  // 插入排序
  insertSort: arr => {
    var temp; // temp变量用于临时存储待插入元素
    for (var i = 1; i < arr.length; i++) {
      // 外层循环相当于选择插入的位置
      temp = arr[i];
      //从前往后查找插入位置
      for (var j = i; j > 0 && arr[j - 1] > temp; j--) {
        // 内层循环和插入当前位置之前的元素进行比较
        arr[j] = arr[j - 1]; //将大于temp的arr[j]元素后移
      }
      arr[j] = temp;
    }
    return arr;
  },
  
  // 选择排序
  selectSortS: arr => {
    var minIndex; //定义minIndex变量用于存储每一趟比较时的最小数的下标
    for (var i = 0; i < arr.length; i++) {
      // 外层循环改变当前默认元素的下表
      minIndex = i;
      for (var j = i + 1; j < arr.length; j++) {
        // 内层循环找当前最小元素的小标
        if (arr[minIndex] > arr[j]) {
          minIndex = j;
        }
      }
      //每轮比较后若arr[i]不是我们需要的最小那个数,则进行交换
      if (minIndex !== i) {
        [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
      }
    }
    return arr;
  },

 // 快速排序
  quickSort: arr => {
    if (arr.length <= 1) {
      // 如果数组只有一个数,就直接返回;
      return arr;
    }
    var num = Math.floor(arr.length / 2); //找到中间数的索引值,如果是浮点数,则向下取整
    var newValue = arr.splice(num, 1); //找到中间数的值
    var left = [],
      right = [];
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] < newValue) {
        left.push(arr[i]); //基准点的左边的数传到左边数组
      } else {
        right.push(arr[i]); //基准点的右边的数传到右边数组
      }
    }
    return quickSort(left).concat(newValue, quickSort(right)); //递归不断重复比较
  },
数组去重复
// 自定义添加方法去重复方法  可以是各种类型
  // var arr3= [0, 1, '1', true, 5, true, false, undefined, undefined, null, null];
  unique: arr => {
    var hash = {},
      result = [],
      type = "",
      item;
    for (var i = 0; i < this.length; i++) {
      item = this[i];
      type = Object.prototype.toString.call(item); // 专门用来判断字符串的类型的
      if (!hash[item + type]) {
        hash[item + type] = true;
        result.push(item);
      }
    }
    return result;
  }
  // console.log(unique(arr3));
};
数组扁平化处理
flattenOne: arr => {
    var res = [];
    for (var i = 0; i < arr.length; i++) {
      if (Array.isArray(arr[i])) {
        res = res.concat(flattenOne(arr[i]));
      } else {
        res.push(arr[i]);
      }
    }
    return res;
  },
  
  // reduce
  flattenTwo: arr => {
    return arr.reduce(function(prev, item) {
      return prev.concat(Array.isArray(item) ? flattenTwo(item) : item);
    }, []);
  },
  
  // 扩展运算符
  flattenThree: arr => {
    while (arr.some(item => Array.isArray(item))) {
      arr = [].concat(...arr);
    }
    return arr;
  },
关于100盏灯的按钮
// 关于 100 盏灯的点击, 规律找 每个数的公约数(可以被开平方的数)
var findOpenLight = {
  arr: [],
  createArr: function () {
    for (let i = 1, l = 100; i <= l; i++) {
      this.arr.push(i)
    }
    return this.sqrt(this.arr)
  },
  sqrt: function(arr) {
    let newArr = arr.filter((item, index, arr) => {
      return Math.sqrt(item).toString().indexOf('.') === -1
    })
    return newArr
  }
}
console.log(findOpenLight.createArr())
编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
 // 已知如下数组:var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
// 编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]
// 扁平化
let flatArr = arr.flat(4)
// 去重
let disArr = Array.from(new Set(flatArr))
// 排序
let result = disArr.sort(function(a, b) {
    return a-b
})
console.log(result)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

// 链式写法 
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]
Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})

// 自定义偏平化处理兼容写法
let arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
let unique = function(arr) {
  while (arr.some(item => Array.isArray(item))) {
    arr = [].concat(...arr);
  }
  return arr;
};
function flatUniqueSort(arr) {
  if (Array.prototype.flat) {
    return Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})
  } else {
    return Array.from(new Set(unique(arr))).sort((a,b)=>{ return a-b})
  }
}

flatUniqueSort(arr)
不起眼的金典面试题
// 以下函数的输出结果
  function Foo () {
    getName = function () { alert(1) }
    return this
  }
  Foo.getName = function () { alert(2) }
  Foo.prototype.getName = function () { alert(3) }
  var getName = function () { alert(4) }
  function getName () { alert(5) }
  
  Foo.getName(); // 2 【直接调用,Foo 本质也是一个object】
  getName(); // 4 【首先会函数声明提升,然后又被var重新声明 】
  Foo().getName(); // 1 【调用Foo函数的时候,getName 被重写】
  getName(); // 1 【上一步被重写】
  new Foo.getName(); // 2
  new Foo().getName(); // 3 调用构造函数并没有显示的返回obj,所以返回新的对象,继承Foo原型中的getName 
  new new Foo().getName(); // 3 原理同上

  变形:
  function Foo () {
    getName = function () { alert(1) }
    return {
       getName: function() {alert(6666)}
    }
  }
  Foo.getName = function () { alert(2) }
  Foo.prototype.getName = function () { alert(3) }
  var getName = function () { alert(4) }
  function getName () { alert(5) }
  
  Foo.getName(); // 2 【直接调用,Foo 本质也是一个object】
  getName(); // 4 【首先会函数声明提升,然后又被var重新声明 】
  Foo().getName(); // 666 【new 一个构造函数,显示的返回了一个对象】
  getName(); // 1 【上一步被重写】
  new Foo.getName(); // 2
  new Foo().getName(); // 666 调用构造函数并没有显示的返回obj,所以返回新的对象,继承Foo原型中的getName 
  new new Foo().getName(); // 666 原理同上
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值