前端常见面试算法题


查看算法源码: https://github.com/huayeer/Algorithm

flag算法

题目:
又称扁平化算法,已知一个不规则的多维多组,输出扁平化的字符串
如array=[‘a’, [‘b’, ‘c’], 2, [‘d’, ‘e’, ‘f’], ‘g’, 3, 4];
需输出字符串a,b,c,2,d,e,f,g,3,4

方法一:递归

function flag1 (array) {
   let newArr = [];
   handleArray (array)
   function handleArray (arr) {
     arr.forEach(item => {
       if (Array.isArray(item)) {
         handleArray(item)
       } else {
         newArr.push(item)
       }
     })
   }
   console.log(newArr.join(','))
 }
 flag1(array)

方法二:toString运算符

function flag2 (array) {
   let toString = Array.prototype.toString;
   Array.prototype.toString = function() {
     // join 默认逗号隔开,所以Array.prototype.toString可以不修改,如果需要其他字符隔开,就需要修改Array.prototype.toString
     return this.join(',')
   }
   console.log(array + '')
   Array.prototype.toString = toString
 }
 flag2(array)

生成父子嵌套树

题目
已知数组

data=[
{id: 23,parentId:23123, name:'aaa'},
{id: 13,parentId:23, name:'bbb'},
....
]

其中id代表当前唯一标识,parentId代表当前元素的伏元素的唯一标识,根据id和parentId判断元素的层级关系,最终组成一个树状结构,最终的数据结构如下:

a = [
	{id: 23, parentId:23213,name:'aaa', children:[
		{id: 13, parentId: 23, name: 'bbb', children: [
				......
		]}
		......
	]}
]

代码如下:
思路:
1、根据data新建一个以id为key的新数组map
2、遍历data,如果item在map中存在父元素,则放到map中相应的children里面
3、删除放入到children里面的item

var map = {};
// 根据data新建一个以id为key的新数组map
data.forEach(function (item) {
  map[item.id] = item;
})

data.forEach(item => {
  let parent = map[item.parent_id]
  if (parent) { 
    if (!parent.children) {
      parent.children = []
    }
    parent.children.push(item) // 如果父元素存在,则放到map中相应的children里面
    delete map[item.id] // 删除已放入到children中的item
  }

})
console.log(map)

一道关于promise的题目

题目:
输出以下运行结果
正确输出为:3 3 4 4 5 2 2 7
思路
第一步、输出同步 Promise实例为同步输出
第二部、输出Promise then
第三部、输出setTimeout

  let int = 1;
  setTimeout(function() {
    console.log(int) // 5 第5个输出
    int = 2
    new Promise((resolve, reject) => {
      resolve()
    }).then(function() {
      console.log(int) // 2 第7个输出
      int = 7
    })
    console.log(int) // 2 第6个输出
  })
  int = 3
  console.log(int) // 3 第1个输出
  new Promise((resolve, reject) => {
    console.log(int) // 3 第2个输出
    return resolve(int = 4)
  }).then(function(res) {
    console.log(int) // 4 第4个输出
    int = 5
    setTimeout(function() {
      console.log(int) // 7 第8个输出
      int = 8
    })
    return false
  })

  console.log(int) // 4 第3个输出

css实现九宫格

题目:
用css实现如下效果
九宫格
代码如下:

<ul>
	<li>1</li>
	<li>2</li>
	<li>3</li>
	<li>4</li>
	<li>5</li>
	<li>6</li>
	<li>7</li>
	<li>8</li>
	<li>9</li>
</ul>
<style type="text/css">
	*{padding:0;height:0;}
	ul{
		width:300px;
		display: flex;
		flex-wrap:wrap;
		padding-top:4px;
	}
	li{
		list-style: none;
		width: 100px;
		height:100px;
		border:4px solid #ddd;
		box-sizing: border-box;
		margin-left: -4px;
		margin-top:-4px;
		line-height:100px;
		text-align: center;
		vertical-align: middle;
	}
	li:nth-child(3n+1) {
		margin-left:0;
	}
	li:hover{
		border-color: #c00;
		z-index: 2
	}
</style>

原生js实现深复制

代码如下:
思路: 递归算法

function deepCody (o) {
   let objCody = {}
   for (let i in o) {
     if (typeof o[i] === 'object') {
       objCody[i] = deepCody(o[i])
     } else {
       objCody[i] = o[i]
     }
   }
   return objCody
 }

 var object = {
   a: 1,
   b: {
     b1: 2,
     b2: {
       b11: 3,
       b22: 4
     }
   },
   c: function () {
     console.log(123)
   }
 }
 var object2 = deepCody(object)
 console.log(object2)

数组去重算法

方法一:新数组中不存在则添加

function distinct1(arr) {
  var newArr = []
   arr.forEach(item => {
     if (newArr.indexOf(item) === -1) {
       newArr.push(item)
     }
   })
   return newArr
 }

方法二:利用filter方法,如果当前元素的下标等于indexOf得到的下标,则加入到新数组

function distinct2(arr) {
   var newArr = [];
   arr.filter((item, index, array) => {
     if(array.indexOf(item) === index) {
       newArr.push(item)
     }
   })
   return newArr
 }

方法三:利用ES6 Set 成员唯一性特性

function distinct3(arr) {
   var newArr = new Set(arr)
   return Array.from(newArr)
 }
 var a = [1,2,3,4,1,3,4,1,null,null,6,7]
 console.log(distinct3(a))

模拟call实现

代码如下:
思路:
1、给object对象添加方法fn 运行object.fn时this便指向了object,从而实现了改变this指向
2、通过arguments获取函数参数

var a = 100
let object = {
  a: 1,
  b: 2
}
function foo (n1, n2) {
  console.log(n1)
  console.log(n2)
  console.log(this.a)
}
Function.prototype.call1 = function (o) {
  let object = o || window
  object.fn = this
  // 获取参数
  let params = []
  for (let i = 1; i < arguments.length; i++) {
    params.push('arguments[' + i + ']')
  }
  // 运行函数
  eval('object.fn(' + params +')')
}
foo.call1(object, 'lisi', 'zhangsan')

点击删除当前行

思路: 使用事件委托提高性能

<ul class="list">
  <li>1 <span class="del">删除</span></li>
  <li>2 <span class="del">删除</span></li>
  <li>3 <span class="del">删除</span></li>
  <li>4 <span class="del">删除</span></li>
  <li>5 <span class="del">删除</span></li>
  <li>6 <span class="del">删除</span></li>
</ul>
<script type="text/javascript">
  class List {
    constructor (sel) {
      this.el = Array.from(document.querySelectorAll(sel))
      var self = this
      this.el.forEach(item => {
        item.addEventListener('click', function (e) {
          if (e.target.nodeName === 'SPAN') {
            self.deleteDom.call(self, e.target)
          }
        })
      })
    }
    deleteDom (target) {
      let self = this
      let findParent = function (node) {
        let parent = node.parentNode
        let root = self.el.find((item) => item === parent)
        if (root) {
          root.removeChild(node)
        } else {
          findParent(parent)
        }
      }
      findParent(target)
    }
  }
  new List('.list')
</script>
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值