总结一些前端笔试面试

1.关于购物的一道题,题目很简单:最近不是双十一吗,小美想要尽可能多的买各种商品,但小美只有一定数额的钱,规定每件商品只能买一件,问最后小美花了多少钱?

用例:

  • 输入购买上限mPrice:188
  • 输入一串以空格分隔的字符串,代表不同的商品的价格pStr:50 42 9 15 105 63 14 30
  • 输出:160

注:mPrice最大不超过一万。

解:

// 获取应买物品的总价格
function getRes(mPrice, pStr) {
  var arr = sortPrice(pStr.split(' '));
  var price = 0;
  for (var i in arr) {
    var tempPrice = price + parseInt(arr[i]);
    if (tempPrice <= mPrice) price = tempPrice;
    else return price;
  }
}

console.log(getRes(188, '50 42 9 15 105 63 14 30'));

// 对所有的物品价格排序
function sortPrice(arr) {
  // 桶排序,内存溢出(失败)
  // var temp = new Array(10000);
  // for (var i in temp) {
  //   temp[i] = 0;
  // }
  // for (var i in arr) {
  //   temp[arr[i]]++;
  // }

  // var res = [];
  // for (var i = 0; i < 10000; i++) {
  //   while (temp[i] != 0) {
  //     res.push(i);
  //     temp[i]--;
  //   }
  // }
  // return res;

  // 冒泡排序
  // var len = arr.length;
  // for (var i = 0; i < len - 1; i++) {
  //   for (var j = 0; j < len - 1 - i; j++) {
  //     // console.log(parseInt(arr[j]));
  //     if (parseInt(arr[j]) > parseInt(arr[j + 1])) {
  //       // console.log(111);
  //       var temp = arr[j];
  //       arr[j] = arr[j + 1];
  //       arr[j + 1] = temp;
  //     }
  //   }
  // }
  // return arr;

  // 通过Object.keys来排序
  var obj = {};
  for (var i in arr) {
    obj[arr[i]] = '';
  }
  return Object.keys(obj);
}

因为给出的上限范围为10000,一开始就想着通过桶排序的思想来做,但是运行时发现出错,报错说JavaScript heap out of memory,也就是内存溢出。接着想到的就是冒泡排序来做,当然其他的排序算法都行,最后想到了一个方法,通过Object.keys()可以针对对象属性均为数字字符串进行数字的排序原理,可以实现简便的语句。思路就不用说什么了吧。

 

2.给一个输入框、一个按钮,输入框中填写一个数字n,点击按钮生成一个n*n的表格,并且要求实现以下的效果:

  • 鼠标虚浮在一个格子上,格子颜色变红,移开恢复(默认颜色为白色);
  • 点击格子,格子颜色变蓝,而且鼠标hover也没什么变化,再次点击,恢复上面的状态;

思路:

  • 通过字符串拼接的方式动态生成表格,并将其渲染出来;
  • 通过hover进行hover效果;
  • 通过在点击格子时为格子添加一个class,并设置样式为background-color: blue !important;来使得格子变蓝的同时不再受hover的影响;
  • 通过事件代理的原理来绑定click事件减少dom操作;

解:

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <style>
    .box-item {
        width: 50px;
        height: 50px;
        box-sizing: border-box;
        display: inline-block;
      	border: 1px solid #000;
        vertical-align: top;
      }
	  
      .box-item:hover {
        background-color: red;
      }

	  .blue {
      	background-color: blue !important;
      }
    </style>
</head>

<body>
  <section>
    <div class="edit-box">
      <input class="num" type="number" value="0" />
      <button class="init-button">初始化盒子</button>
    </div>
    <div class="grid-box">
      <!-- <span class="box-item"></span> -->
    </div>
  </section>
</body>
<script>
  var num = document.getElementsByClassName('num')[0];
  var btn = document.getElementsByClassName('init-button')[0];
  var gridBox = document.getElementsByClassName('grid-box')[0];
  btn.onclick = function () {
    n = num.value;
    var gridStr = '';
    for (var i = 0; i < n * n; i++) {
      gridStr += '<span class="box-item"></span>';
    }
    gridBox.style.width = (n * 50) + 'px';
    gridBox.style.height = (n * 50) + 'px';
    gridBox.innerHTML = gridStr;

    // click点击颜色切换设置
    var flagArr = new Array(n * n);
    for (var i = 0; i < n * n; i++) flagArr[i] = false;
    var boxItems = Array.prototype.slice.call(document.getElementsByClassName('box-item'));
    gridBox.onclick = function (e) {
      console.log(flagArr[0]);
      var target = e.target || e.srcElement;
      var index = boxItems.indexOf(target);
      if (index != -1) {
        if (!flagArr[index]) {
          target.className += ' blue';
        } else {
          removeCla(target, 'blue');
        }
        flagArr[index] = !flagArr[index];
      }
    }
  }

  // 辅助函数
  function removeCla(el, claName) {
    var cla = el.className;
    var arr = cla.split(' ');
    var index = arr.indexOf(claName);
    if (index != -1) {
      arr.splice(index, 1);
      el.className = arr.join(' ');
    }
  }
</script>

</html>

上面的class的操作其实是可以用classlist来进行相应的操作,不过其兼容性会相对差一些。

 

3.一道页面效果的编写题(写了我将近一天。。。再加上一些优化调试。。。),下面给出题目:

请根据提供的psd文件,完成一个静态(HTML)页面的设计,预览如下。

要求:

  • 1. 尽可能按照设计稿样式实现(文字字体除外);
  • 2. 页面应该设计为占满浏览器宽度;
  • 3. 请实现图片轮播效果(可用多张重复图片);
  • 4. 提交HTML文件,便于我们检验。

这道题的代码码我放到我github上一个轮播器总结的demo中:

https://github.com/yaodebian/Carousel/tree/master/js%E5%AE%9E%E7%8E%B0%E8%BD%AE%E6%92%AD%E6%95%88%E6%9E%9C/demo2​github.com

 

4. 已知一个思维导图如下:

该思维导图对应的数据如下:

奴隶社会,非洲,古埃及文明,金字塔
,亚洲,两河流域文明,汉谟拉比法典
,,古印度,种姓制度
,,,佛教的创立
,欧洲,希腊,希腊城邦
,,,雅典民主
,,罗马,城邦
,,,帝国的征服与扩展
,,希腊罗马古典文化,建筑艺术
,,,公历

备注:声明一个 String 变量存储使用即可。

将上述字符串数据按照如下规则转换成与思维导图结构相同的json。

奴隶社会,非洲
,亚洲
,,古印度
,欧洲

转换成的json如下:

{
  "奴隶社会": [
    {
      "非洲": []
    },
    {
      "亚洲": [
        {
          "古印度": []
        }
      ]
    },
    {
      "欧洲": []
    }
  ]
}

请实现如下 JavaScript 函数:

function str2json(str) {

code //你的实现代码

}

题目已经讲的很清楚了,就是将上面格式的数据解析为上面形式的json数据,换言之,解这道题的关键是要弄懂它的一个解析规则。

其实还是很简单的,如下:

代码如下,通过递归的方法解决:

// 由于是在windows下编写,用\r\n作为换行分隔符
var s = "奴隶社会,非洲,古埃及文明,金字塔\r\n,亚洲,两河流域文明,汉谟拉比法典\r\n,,古印度,种姓制度\r\n,,,佛教的创立\r\n,欧洲,希腊,希腊城邦\r\n,,,雅典民主\r\n,,罗马,城邦\r\n,,,帝国的征服与扩展\r\n,,希腊罗马古典文化,建筑艺术\r\n,,,公历";

// main函数
function str2json (str) {
  // 获取每一条规则
  var arr = str.split('\r\n');

  return JSON.stringify(parse(arr));
}

// 输出解析json字符串
console.log(str2json(s));



/* 辅助方法 */
// 获取s头部,的数量
function getPreNum (s) {
  var reg = /^,*/;
  return reg.exec(s)[0].length;
}

// 删除每一条规则第一个,号
function delPreTag (arr) {
  var len = arr.length;
  for (var i in arr) {
    arr[i] = arr[i].substring(1);
  }
}

// 执行解析操作
function parse (arr) {
    // 用于记录第二层级数据项(根下一项)的起始位置
    var indexArr = [];

    // 输出结果obj
    var obj = {};
  
    // 1. 首先先将根属性取出
    // 如果数组为空,直接返回一个空的数组
    if (arr.length === 0) return obj; 
    // 如果数组中仅包含一项,并且没有','标识,则直接返回该字段
    if (arr.length === 1 && arr[0].indexOf(',') === -1) {
      return arr[0];
    }
    var index =  arr[0].indexOf(',');
    var root = arr[0].substring(0, index);
    obj[root] = [];
    arr[0] = arr[0].substring(index);
  
    // 2. 获取第二层级数据项(根下一层数据)的起始下标
    for (var i = 0; i < arr.length; i++) {
      // 如果头部,数量为1
      if (getPreNum(arr[i]) === 1) {
        indexArr.push(i);
      }
    }
  
    // 临时的一个数组,用于存放每个二级分组
    var tempArr = [];
    // 3. 将每条规则的第一个,号删除
    delPreTag(arr);

    // 4. 将每一个二级分组提取到tempArr中
    for (var i = 0; i < indexArr.length; i++) {
      if (i !== indexArr.length - 1) {
        tempArr.push(arr.slice(indexArr[i], indexArr[i + 1]));
      } else {
        tempArr.push(arr.slice(indexArr[i]));
      }
    } 

    // 5. 对tempArr进行遍历回调
    for (var i in tempArr) {
      obj[root].push(parse(tempArr[i]));
    } 
  
    return obj;
}

 

5. 关于js中的变量重复声明问题

对于es5,对同一个变量声明两次,不会报错,后声明的会值会覆盖先声明的;

对于es6,比如说同一个变量声明两次,会报错SyntaxError: Identifier 'xxx' has already been declared

 

6. display有哪些值

这里就不一一研究,之后单独总结一下。

提一下display: block、inline-block、inline这两者的区别有哪些?

  • block设置的元素前后有换行,并且可以设置宽高;
  • inline设置的元素前后没有换行,不可以设置宽高;
  • inline-block设置的元素前后没有换行,可以设置宽高;

另外,简单说说inline-block的baseline问题,看几张图就知道了:

 

。。。

以下单独总结

。。。

7. 事件绑定的方法

8. 事件循环机制

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值