前端面试整理自用2

下列四种的判断数组的区别

typeof  Object.prototype.toString.call Array.isArray instanceof

typeof

typeof [] // object ,并且typeof null 也为object 不准
Object.prototype.toString.call([]) // "[object Array]" 准确
 Array.isArray([]) // true  返回的是boolean  准确
[] instanceof Array  // true ,[]会随着__proto__查找如果能找到Array.prototype则返回true
立即执行函数
var a = 10;
(function a(){
   a = 20
  console.log(a)
})()
/*
  ƒ a(){
   a = 10
  console.log(a)
}
*/

因为自执行函数名称不会被改变
如何打印10 或者打印 20

  var a = 10;
(function a(a){
   a = 20
  console.log(a)
})(a)
  // 20
  var a = 10;
(function a(a){
  window.a = 20
  console.log(a)
})(a)
  // 10
为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片
  • 1 不会占用ajax 请求支援
  • 2 触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据
  • 3 跨域友好
  • 4 gif 体积小
箭头函数的问题
* 箭头函数 的this会随着生成的时候固定的
* 箭头函数 不能用作Generator 函数
* 箭头函数 不能使用arguments 
* 箭头没有 不能用new
    由于箭头函数没有 prototype
    this 不可变化

实现finally

Promise.prototype.finally=function (cb) {
        let p = this.constructor
        return this.then(
          val=>  p.resolve(cb()).then(()=> val),
          err=>  p.resolve(cb()).then(()=> err)
            )
}

retina 1px

利用box-shadow

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        .div{
            width: 400px;
            height: 400px;
            margin: 200px;
            margin-left: 500px ;
            box-shadow: inset 1px -1px 1px -1px #c8c7cc;        }
    </style>
</head>
<body>
    <div class="div">111</div>
</body>
</html>>

利用 div+伪类+transform scale
单个边框

.scale-1px{
                position: relative;
                border:none;
                width: 300px;
                height: 300px;
            }
            .scale-1px:after{
                content: '';
                position: absolute;
                bottom: 0;
                background: #000;
                width: 100%;
                height: 1px;
                -webkit-transform: scaleY(0.5);
                transform: scaleY(0.5);
                -webkit-transform-origin: 0 0;
                transform-origin: 0 0;
            }

四个边框

.scale-all{
                position: relative;
                overflow: hidden;
                height: 400px;
                width: 400px;
                border: none;
            }
            .scale-all:after{
                content: '';
                width: 200%;
                height: 200%;
                position: absolute;
                transform-origin: 0 0;
                border: 1px solid #000;
                transform: scale(0.5);
                left: 0;
                top: 0;
            }

transform-origin: 0 0; 表示旋转轴,0 0 box 的左上角

HMR 原理

sss.jpg
  • 1 webpack 监控文件系 统监控文件系统,若发生变化,则存入缓存中
  • 2 webpack-dev-server 中 dev-server-midware通过 webpack 暴露的api 监控 文件变化
  • 3 并通过webpack-dev-server 发送给 webpack-dev-server/client 连接方式 是 websocket 的通信模式
  • 4 webpacl-dev-server/client 获取更加文件的 hash 值
    *5 webpack/hot/dev-server 来判断是热跟新还是 重新加载
    *6HotModuleReplaceMent Runtime 是HMR的中枢,
  • 7他通过jsonpMainTemplate Runtime 像webpack-dev-server 建立 通信,来获取更新的文件hash
  • 8 9 都是获取json文件
  • 10 11 根据hash 获取文件依赖,进行热更新,通过重新更新render 函数

var ,let ,const 的区别

  • var 会变量提升,值允许改变
  • let 不提升,值允许改变
  • const 不提升,不值允许改变
原因
  • var的时候会预分配空间,不做类型检查
  • let 时候不会预分配空间,检查栈中是否存在当个变量,存在报错
    *let 时候不会预分配空间,检查栈中是否存在当个变量,存在报错,切不许修改

前端涉及加密

base64 编码

对数据进行base64进行编码
运用:cookie的编码

哈希算法

是 a 利用哈希算法 转换为 b ,并且这么转换的过程是不可变化的,md5算法
试用场景:重置密码时发送给你的严重邮箱,以及随机密码

哈希加盐(Adding Salt)

哈希算法会被穷举法和寻找碰撞法 解密,可以通过新加数据,例如

let salt = self.getCookie('salt') ? self.getCookie('salt') : uuid;
let sign =Sha1hex(`${token}${taxpayerId}${self.state.submitParams.companyName}${uuid}${salt}`);//salt为盐值

如果盐的值太短,就用增加长度(短盐),并且随机值盐,经常替换(复用盐)

慢哈希

例如,增加哈希的计算的次数,让如果计算一次所需要的时间是1微秒,那么计算1百万次就需要1秒钟。假如攻击一个密码所需的rainbow table有1千万条,建立所对应的rainbow table所需要的时间就是115天。这个代价足以让大部分的攻击者望而生畏
‘例子:PBKDF2

XOR

利用 位运算

1 ^ 1 // 0
0 ^ 0 // 0
1 ^ 0 // 1
0 ^ 1 // 1

使用不同的key 解密

function getXOR(message, key) {  const arr = [];  //假设 key 是32位的 
   for (let i = 0; i < 32; i++) {   
       const  m = parseInt(message.substr(i, 1), 16);    
       const k = parseInt(key.substr(i, 1), 16);    
      arr.push((m ^ k).toString(16));  
     }  
return arr.join('');
}
加密
  • 对称加密

  • 非对称加密

  • 数子签名,字签名主要用于确认信息来源于特定的主体且信息完整、未被篡改,发送方生成签名,接收方验证签名

  • crypto

接口防刷
  • 网关控制流量洪峰,对在一个时间段内出现流量异常,可以拒绝请求
  • 源ip请求个数限制。对请求来源的ip请求个数做限制
  • http请求头信息校验;(例如host,User-Agent,Referer)
  • 对用户唯一身份uid进行限制和校验。例如基本的长度,组合方式,甚至有效性进行判断。或者uid具有一定的时效性
  • 前后端协议采用二进制方式进行交互或者协议采用签名机制
  • 人机验证,验证码,短信验证码,滑动图片形式,12306形式
支持拖拽的弹窗
拖拽 mouseup mouseup 只支持 pc ,移动端是touch 事件。drag 事件问题:会回弹,用于文件拖拽比较合适
class Dialog{
    constructor(title){
        this.title = title
        const box = document.createElement("div");
        const boxstyle = [
            ["background","#000000"],
            ["top","0"],
            ["position","fixed"],
            ["left","0"],
            ["right","0"],
            ["bottom","0"],
            ["z-index","9"],
            ["opacity","0.5"]
        ]
        boxstyle.forEach(ele => {
            box.style[ele[0]] = ele[1]
        });
        const boxDiv = document.createElement("div")
        // boxDiv.setAttribute("draggable","true")
        boxDiv.setAttribute('id',"dragdiv")
        const trans = lib.flexible.px2rem
        console.log(trans("300px"),"dfsdfsd")
        const boxDivstyle = [
            ["top",trans((document.documentElement.clientHeight/2-150)+"px")],
            ["position","absolute"],
            ["left",trans((document.documentElement.clientWidth/2-200)+"px")],
            ["width",trans('400px')],
            ["height",trans('300px')],
            ["z-index","11"],
            ["background","#fff"]
        ]
        boxDivstyle.forEach(ele => {
            boxDiv.style[ele[0]] = ele[1]
        });
        const titleDiv = document.createElement("div")
        titleDiv.innerHTML = this.title
        const titlestyle = [
            ["font-size",trans("50px")],
            ["text-align","center"],
            ["margin-top",trans("60px")]
        ]
        titlestyle.forEach(ele => {
            titleDiv.style[ele[0]] = ele[1]
        });
        const jhDivStyle = [["display","flex"]]
        const jhDiv   = document.createElement("div")
        jhDivStyle.forEach(ele => {
            jhDiv.style[ele[0]] = ele[1]
        });
        const argeDIvStyle = [
            ["font-size",trans("40px")],
            ["text-align","center"],
            ["width","50%"],
            ["margin-top",trans("60px")]
        ]
        const argeDIv = document.createElement("div")
        const disaDiv = document.createElement("div")
        argeDIv.innerHTML = "同意"
        disaDiv.innerHTML = "取消"
        argeDIvStyle.forEach(ele => {
            argeDIv.style[ele[0]] = ele[1]
            disaDiv.style[ele[0]] = ele[1]
        });
        document.body.appendChild(box)
        box.appendChild(boxDiv)
        boxDiv.appendChild(titleDiv)
        boxDiv.appendChild(jhDiv)
        jhDiv.appendChild(argeDIv)
        jhDiv.appendChild(disaDiv)
        this.box = box
    }
    open(){
        const trans = lib.flexible.px2rem
        if(this.box) document.body.appendChild(this.box)
        const dragdiv = document.getElementById("dragdiv")
        let leftx = 0
        let lefty = 0

        dragdiv.addEventListener("mousedown",(e)=>{
            // 计算鼠标位置到当前点击盒子的位置,用于end时候减值
            leftx = e.clientX -dragdiv.getBoundingClientRect().left
            lefty = e.clientY-dragdiv.getBoundingClientRect().top
            console.log(leftx,lefty)
        })
        document.addEventListener("mouseup",(e)=>{
            const {clientX,clientY} = e

            dragdiv.style.top = trans((clientY-leftx)+"px")
            dragdiv.style.left = trans((clientX-lefty)+"px")
        })
        // h5方案
        dragdiv.addEventListener("touchstart",(e)=>{
            console.log(e,"eeeeeee")
            leftx = e.changedTouches[0].clientX -dragdiv.getBoundingClientRect().left
            lefty = e.changedTouches[0].clientY-dragdiv.getBoundingClientRect().top
            console.log(leftx,lefty)
        })
        document.addEventListener("touchend",(e)=>{
            const {clientX,clientY} = e

            dragdiv.style.top = trans((e.changedTouches[0].clientY-leftx)+"px")
            dragdiv.style.left = trans((e.changedTouches[0].clientX-lefty)+"px")
        })
    }
    close(){
        document.body.removeChild(this.box)
    }
}
let dialog = new Dialog("mmm")
dialog.open()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容