面试时,你被要求手写常见原理了吗?

经典Flex布局 ❤️

如今 Flex布局 不管是移动端还是PC端的应用已经非常广泛了,下面我列举几个平时项目中非常常见的几个需求。以下例子我们都以Vue项目和js为例~

flex布局均匀分布后换行问题

需求一:ul下有多个li,每三个li排一列,多余的换行显示。

很显然,绝大部分的小伙伴都会使用Flex布局,很显然会出现一个问题就是如果li是3的倍数的话就能正常显示,若不是的话,布局就不是产品经理满意的结果。

	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;

在这里插入图片描述
解决方案:

我们在ul的底部新增li,个数为数组总长度%3的余数即可。

vue

<li class="item" style="border: none;" v-for="(ite, idx) in (3-list.length%3)==3?0:(3-list.length%3)" :key="idx"></li>

js

  <ul id="ul">
  </ul>
  
  <script>
    var ul = document.getElementById('ul');

    for(let i =0;i<8;i++){
      var li = document.createElement('li');
      li.innerText=i;
      ul.appendChild(li);
    }

    for(let i=0;i< ((3-8%3)==3?0:(3-8%3)) ;i++){
      var li = document.createElement('li');
      li.style.border = "none";
      ul.appendChild(li);
    }
  </script>
  <style>
    ul,li{
      list-style: none;
    }
    ul{
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
    }
    li{
      width:30%;
      height: 100px;
      border: 1px solid black;
      margin: 20px 0;
      align-items: center;
    }
  </style>

在这里插入图片描述

统计网页中出现的标签 去重

实现步骤:

  1. 获取所有的DOM节点
  2. NodeList集合转化为数组
  3. 获取数组每个元素的标签名
  4. 去重
new Set([...document.querySelectorAll('*')].map(ele=>ele.tagName)).size

在这里插入图片描述

防抖和节流

如今前端界面效果越来越复杂,有一些频繁操作会导致页面性能和用户体验度低。像:输入框搜索会频繁调端口接口、放大缩小窗口等。

防抖 - debounce 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

const debounce = (fn, delay) => {
  let timer = null;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};

节流 - throttle 当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

const throttle = (fn, delay = 500) => {
  let flag = true;
  return (...args) => {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn.apply(this, args);
      flag = true;
    }, delay);
  };
};

Jsonp的原理

原理:

首先在客户端注册一个callback,然后把callback的名字传给服务器。此时,服务器先生成json数据,然后以javascript语法的方式,生成function,function名字就是传递上来I带参数jsonp。最后将json数据直接以入参的方式,放置function中,这样就生成js语法的文档,返回给客户端。客户端浏览器,解析script变迁,并执行返回javascript文档,此时数据作为参数,传入了客户端预先定义好的callback函数里。简单的说,就是利用script标签没有跨域限制的“漏洞”来达到与第三方通讯的目的。

function jsonp({url, params, cb}) { 
   return new Promise((resolve, reject) => {
     window[cb] = function (data) {  // 声明全局变量
        resolve(data)
        document.body.removeChild(script)
      }
      params = {...params, cb}
      let arrs = []
      for(let key in params) {
         arrs.push(`${key}=${params[key]}`)
      }
      let script = document.createElement('script')
      script.src = `${url}?${arrs.join('&')}`
      document.body.appendChild(script)
   })
}

jsonp的缺点:

  1. 只能发送Get请求 不支持post put delete
  2. 不安全 xss攻击

new的原理

简单来说,四步:

1、在函数内部自动创建一个对象
2、修改函数的作用域,将this指向该对象
3、为该对象添加属性和方法
4、返回该对象

 function _new () {
		var obj = new Object();
		  var [func, ...args] = [...arguments];
		  obj.__proto__ = func.prototype;
		  var result = func.call(obj,...args);
		  if(result && ( typeof(result) === 'object' ||  typeof(result) === 'Function')){
		    return result;
		  }
		  return obj;
	}
	function Animal(name,age){
		  this.name = name;
		  this.age = age;
	}
	//通过new创建构造实例
	let dog1 = new Animal('dog1',2);
	console.log(dog1.name) // dog1
	console.log(dog1.age)//2
	
	//通过_new方法创造实例
	let dog2 = _new(Animal,'dog2',3);
	console.log(dog2.name)//dog2
	console.log(dog2.age) //3

去重❤️

let arr2 = [1, 2, 3, 2, 33, 55, 66, 3, 55];

第一种:

let newArr = [];
   arr2.forEach(item => {
       if(newArr.indexOf(item) == '-1') {
           newArr.push(item);
       }
   })
console.log(newArr);

// (6) [1, 2, 3, 33, 55, 66]

第二种: 推荐

let newArr = [...new Set(arr2)];
console.log(newArr);

// (6) [1, 2, 3, 33, 55, 66]

第三种:

Array.from方法可将Set结果转为数组

所以 还可以

let newArr = Array.from(new Set(arr2));
console.log(newArr);

// (6) [1, 2, 3, 33, 55, 66]

合并 ❤️

let arr3 = ['a', 'b']
let arr4 = ['c', 'd']

方法一:ES5

let arr5 = arr3.concat(arr4);
console.log(arr5);

// ['a', 'b', 'c', 'd']

方法二:ES6

let arr6 = [...arr3, ...arr4];
console.log(arr6);

// ['a', 'b', 'c', 'd']

展平❤️

let arr7 = [1, 2, [3, 4], [5, 6, [7, 8, 9]]];

第一种: flat

let arrNew = arr7.flat(Infinity);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

第二种:

let arrNew = arr7.join().split(',').map(Number);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

第三种:

let arrNew = arr7.toString().split(',').map(Number);
console.log(arrNew);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

第四种:

const flattern = (arr) => {
     const result = []
     arr.forEach((item) => {
         if (Array.isArray(item)) {
              result.push(...flattern(item))
         } else {
              result.push(item)
         }
    })
    return result
}
flattern(arr7);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

第五种:

function flatten(arr) {
    return [].concat(
        ...arr.map(x => Array.isArray(x) ? flatten(x) : x)
    )
}
flattern(arr7);

// (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

冒泡排序❤️

let arr = [1, 44, 6, 77, 3, 7, 99, 12];

冒泡排序算法的原理如下:

1、 比较两个相邻的元素,若前一个比后一个大,则交换位置
2、 第一轮的时候最后一个元素应该是最大的一个
3、 对所有的元素重复以上的步骤,除了最后一个

function bubbleSort(arr) {
    for(let i=0; i<arr.length; i++) {
        for(let j=0; j<arr.length - i - 1; j++) {
            if(arr[j+1] < arr[j]) {
                let temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    return arr;
}
console.log(bubbleSort(arr));

// [ 1, 3, 6, 7, 12, 44, 77, 99 ]

注意:最后一个元素不用比较。

快速排序 ❤️

let arr = [1, 44, 6, 77, 3, 7, 99, 12];

快速排序算法的原理如下:

1、 找基准(一般是以中间项为基准)
2、 遍历数组,小于基准的放在left,大于基准的放在right
3、递归

function quickSort(arr) {
    if(arr.length <= 1) return arr;
    let mid = Math.floor(arr.length / 2);
    let midItem = arr.splice(mid, 1)[0];
    let leftArr = [];
    let rightArr = [];
    for(let i=0; i<arr.length; i++) {
        let current = arr[i];
        if(current >= midItem) {
            rightArr.push(current);
        } else {
            leftArr.push(current);
        }
    }
    return quickSort(leftArr).concat([midItem], quickSort(rightArr));
}

console.log(quickSort(arr));

// [ 1, 3, 6, 7, 12, 44, 77, 99 ]

最后

一起学习前端,共同进步!❤️❤️❤️❤️❤️❤️

文章参考:https://juejin.im/post/5e8153bf6fb9a03c840d509d#heading-25

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值