20 前端面试javascript/es6重难点:常见排序、数组/字符串方法、es6语法、DOM操作、异步函数、高阶函数、this绑定、原型链函数、继承原理、手写深拷贝、防抖节流、等知识点汇总

最近的几次面试、笔试都被考到了相关js语法,算法也不能少....

自建一个文件夹,保存js常考笔试面试题:

包含es6、this绑定、异步执行顺序分析

1.原型链

function Parent(name){
                console.log(name);
                this.name = name
            }

            function Child(name){
                Parent.call(this,name)
            }

            Child.prototype = new Parent();

            var child1 = new Child("child1")
            console.log(1111)
            console.log(child1)
            console.log(Child.prototype)

2.冒泡、捕获的第三个参数:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件机制</title>
</head>
<body >

    <div id="parent" style="height: 400px;width: 400px;background-color: cadetblue">
        <div id="child" style="height: 200px;width: 200px; margin:0 auto; background-color: bisque" onclick="console.log('捕获之前 child self click')">
        </div>
    </div>
    <script>
        document.body.addEventListener("click",function () {
            console.log('捕获 body click')
        },true);
        document.getElementById('parent').addEventListener("click",function () {
            console.log('捕获 parent click')
        },true);
        document.getElementById('child').addEventListener("click",function () {
            console.log('捕获 child click')
        },true);
        document.getElementById('parent').onclick =function(){
            console.log('捕获之后 parent self click')
        }

        
        document.body.addEventListener("click",function () {
            console.log('冒泡 body click')
        },false);
        document.getElementById('parent').addEventListener("click",function () {
            console.log('冒泡 parent click')
        },false);
        document.getElementById('child').addEventListener("click",function () {
            console.log('冒泡 child click')
        },false);
        document.body.onclick =function(){
            console.log('冒泡之后 body self click')
        }
    </script>

</body>
</html>

3.数组操作
 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        console.log("----------------------------111111")

        let arr = [];
        arr.push(1, 2, 3, 4, 5, "12345")


        console.log(...arr)
        console.log("----------------------------22222")

        arr.splice(1, 3, "abc")
        console.log(...arr)

        


    </script>
</body>

</html>

4.数组方法:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>

        // let arr = [];
        // let len = 100;
        // for (let i = 0; i < len; i++) {
        //     let x = Math.floor(Math.random()*len);
        //     console.log(x);
        //     arr.push(x)
        // }
        // console.log(arr)

        // console.log("=================1111111111111111");
        // var p1 = [];
        // var p2 = [];
        // var p3 = [];
        // var p4 = [];
        // var p5 = [];
        // for(let i = 0;i<arr.length;i++){
        //     if(arr[i]<len*0.5 && arr[i]>0){
        //         debugger
        //         console.log(arr[i]);
        //         // console.log("-----1")
        //         p1.push(arr[i])
        //     }
        //     else {
        //         // console.log("-----2")
        //         p2.push(arr[i])

        //     }
        // }
        // console.log(p1.length)
        // console.log(p2.length)


        // for(let i =0 ;i<100;i++){
        //     let x = Math.ceil(Math.random()*100)
        //     // console.log(x)
        // }
        // console.log(first)
        console.log("----------------------------111111")

        let arr = [];
        arr.push(1, 2, 3, 4, 5, "12345")


        console.log(arr)
        console.log("----------------------------22222")

        arr.splice(1, 3, "abc")
        console.log(arr)

        console.log("----------------------------333333 删除")
        let arr2 = [1, 2, 3, 54, 5, 6]
        // let arr2n = arr2.pop()
        // console.log(arr2n)

        // let x = arr2.shift()
        // console.log(x)

        console.log("----------------------------333333 改")

        console.log("splice")

        console.log("-------------------------4444444444查")
        let arr4 = [1, 34, 4, 5, 5, 6, 6, 6, 67, 7]
        // console.log(arr4.indexOf(5))
        console.log(arr4.includes(5))

        console.log("-------------------------5555555555555》》》》》》》》》》》》》》》》  排序")

        let paixu = [1, 32, 4, 5, 6, 6, 6, 67, 7, 7, 7, 7, 7, 9834634764587326, 37, 346, 4, 634, 673, 7, 37, 72, 62, 6, 6, 4, 472, 1, 74775873, 8, 348, 1]
        console.log(...paixu.reverse())
        console.log(...paixu.sort())


        console.log("-------------------------666666666666》》》》》》》》》》》》》》》》》  转换")

        let zh = ["jiba", '123', 'erg>gt', '14,', '  32572 385 93  7892357ew ryg89 9^&*()(*&UIHG*&', ' 31  4 4a  n', 'as ,', '234 234 , rwf f, , , , ', '13 43 ', 'asf . . .fa.s  , ']
        // console.log(first)

        let zh1 = zh.join("<--->")
        console.log(zh1)


        console.log("-------------------------7777777777777777》》》》》》》》》》》》》》》》》  迭代操作:forEach  filter   map")
        
        let feArr =  [1, 2, 3, 4, 5, 4, 3, 2, 1];
        feArr.forEach((item,index,array)=>{
            // item=item+1
            console.log("item是:",item," , index是:",index, "  arr自己是: ",array)
        })
        console.log(feArr)
        console.log("-----")

        let filterArr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
        let newFtArr = filterArr.filter((item,index,array)=> {
            return item%3 ==0
        })
        console.log(newFtArr)

        console.log("-----")

        let mapArr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
        let newMpArr = mapArr.map((item,value,array)=>{
            return item*=10
        });
        console.log(newMpArr);

    </script>
</body>

</html>

5.字符串方法:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        console.log("--------------------------1字符串方法--------------------------")

        console.log("-------------------11111增加")
        let stringValue = "hello string is here !!!"
        let newString = stringValue.concat(" end of the newString");
        console.log(newString)

        console.log("-------------------2222222删除")
        let shanString = "hello string is here !!!"
        console.log(shanString.slice(6))
        console.log(shanString.substring(0, 3))

        console.log("-------------------333333 改")

        let gaiString = "   hello string is here !!!  "
        console.log(gaiString.length)
        let gaiedString = gaiString.trim();
        console.log(gaiedString.length)
        console.log(gaiString.length)

        console.log("-------------------44444444  查找")
        let chaString = "   hello string is here !!!  "

        console.log(chaString.charAt(3))
        console.log(chaString.includes("hello"))



        console.log("-------------------555555  转换")
        let changeString = "   hello . asfd. ey45ygf. .at45 .fs.dfas. s.f sd. .fs.f astr.a s.f.asf.s.3.4.5.eg.f45..t.ing is here !.!!  ";
        let aftArr = changeString.split(".")
        console.log(...aftArr)


        console.log("-------------------6666666 test function")

        var i = 101;
        for (; i--;) {
            // console.log(i); // 从 1001 打印到 0
        }


        console.log("-------------------77777 100内质数function")

        

    </script>
</body>

</html>

6. es6 常见语法:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>

        var p1 = Promise.resolve(1);
        var p2 = Promise.resolve(p1);
        var p3 = new Promise(function (resolve, reject) {
            resolve(1);
        });
        var p4 = new Promise(function (resolve, reject) {
            resolve(p1);
        });

        // 宏任务: 
        // 微任务: 
        console.log(p1, p2, p3, p4)


        console.log(p1 === p2);
        console.log(p1 === p3);
        console.log(p1 === p4);
        console.log(p3 === p4);
        p4.then(function (value) {
            console.log('p4=' + value);
        });

        p2.then(function (value) {
            console.log('p2=' + value);
        })

        p1.then(function (value) {
            console.log('p1=' + value);
        })
    </script>
</body>

</html>

7.异步加载对于浏览器
 

8.节流
 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <button>按钮</button>

  <input type="text">
  
  <!-- CDN引入: 网络的js文件 -->
  <!-- <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.4/underscore-umd-min.js"></script> -->
  <!-- 本地引入: 下载js文件, 并且本地引入 -->
  <script src="./js/underscore.js"></script>

  <script>
    // function hythrottle(fn, interval) {
    //   let startTime = 0

    //   const _throttle = function() {
    //     const nowTime = new Date().getTime()
    //     const waitTime = interval - (nowTime - startTime)
    //     if (waitTime <= 0) {
    //       fn()
    //       startTime = nowTime
    //     }
    //   }

    //   return _throttle
    // }
    //11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    function hythrottle(fn,interval){
      let startTime = 0 
      let cnt
      const _throttle = function(){
        const nowTime = new Date().getTime()
        const waitTime = nowTime - startTime
        if(interval<=waitTime){
          fn()
          startTime = nowTime
        }
      }
      return _throttle
    }
  </script>

  <script>
    // 1.获取input元素
    const inputEl = document.querySelector("input")

    // 2.underscore节流处理代码
    // let counter = 1
    // inputEl.oninput = _.throttle(function() {
    //   console.log(`发送网络请求${counter++}:`, this.value)
    // }, 1000)

    // 3.自己实现的节流函数
    let counter = 1
    inputEl.oninput = hythrottle(function() {
      console.log(`发送网络请求${counter++}:`, this.value)
    }, 1000)


  </script>

</body>
</html>

为什么能狗执行限制时间间隔的函数?

返回的是一个函数!!!!

因为是一个闭包,startTime可以被从里面访问到,下次比较的是前一次的时间,

还有一种写法:

function throttle(fn, delay) {
	let canUse = true;
  return function() {
    if (canUse) {
    	fn.apply(this, arguments);
      canUse = false;
      setTimeout(() => canUse = true, delay);
    }
  }
    
    let F = true;
    return function(){
    if(F=true){
        fn.apply(this,arguments);
        F= false;
        setTimeout(()=>f=true,delay);
    }
}




}

9 快排

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>


        var arr = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48];

        function quickSort(arr) {
            if (arr.length <= 1) return arr;
            var leftArr = [], rightArr = [], q = arr[0];
            for (var i = 1; i < arr.length; i++) {
                if (arr[i] > q) {
                    rightArr.push(arr[i]);
                } else {
                    leftArr.push(arr[i]);
                }
            }

            return [].concat(quickSort(leftArr), [q], quickSort(rightArr));
        }
        console.log(quickSort(arr))
        console.log(1)
    </script>
</body>

</html>

10 DOM:


虚拟node:node效率太低。190个属性。而现在只要3个步骤 》》》

  • JavaScript 很快和直接操作 DOM 很慢,这是 Virtual DOM 得以实现的两个基本前提。
    • 得益于 V8 引擎的出现,让 JavaScript 可以高效地运行,在性能上有了极大的提高。
    • 直接操作 DOM 的低效和 JavaScript 的高效相对比,为 Virtual DOM 的产生提供了大前提。
  • 三个步骤 》》》生成 Virtual DOM 树-比两棵树的差异-更新视图。

11.判断是否在页面可视区域:

// 防抖/节流
  const scrollListenerHandler = throttle(() => {
    if (el === window) {
      clientHeight.value = document.documentElement.clientHeight
      scrollTop.value = document.documentElement.scrollTop
      scrollHeight.value = document.documentElement.scrollHeight
    } else {
      clientHeight.value = el.clientHeight
      scrollTop.value = el.scrollTop
      scrollHeight.value = el.scrollHeight
    }
    if (clientHeight.value + scrollTop.value >= scrollHeight.value) {
      console.log("滚动到底部了")
      isReachBottom.value = true
    }
  }, 100)

clinetHeight+scrollATop>scrollTop就能判断是否到了底部

11 insertAfter:

判断是否有下一个子元素节点----》》》1.如果有就在下一个兄弟元素前插入,2.没有就直接在当前附加一个子节点
 

HTMLElement.prototype.insertAfter = function(target, afterNode) {
  var nextElem = afterNode.nextElementSibling;
  if (nextElem) {
    this.insertBefore(target, nextElem);
  } else {
    this.appendChild(target);
  }
}

12 逆序排列元素的子节点:

...***function () {

    var childElem = this.children,
      childrenLen = childElem.length,
      fragment = document.createDocumentFragment();

      for (var i = childrenLen - 1; i >= 0; i--) {
          fragment.appendChild(childElem[i]);
      }
      this.appendChild(fragement)
 
    
}

13.mouseOver 和mouseEnter有什么区别?

切换了都会处罚,只有进入才会:

所以要多一些,第一种


14.找一个最近的公共父亲节点?
 

***findFather(a,b){
    for(;a;a=a.parentNode){
    
        if(a.contains(b)){
            return a;
        }        

    }
}

15.手写深拷贝?

function deepCopyMyself(obj,cloneObj = new WeakMap()){
      if(obj==null || typeof obj ==='Object' ||){
        return obj ;
      }
      if(cloneObj.has(obj)){
        return cloneObj.get(obj);
      }
      //处理对象
      let newObj = {}
      cloneObj.set(obj,newObj);
      for(let i in obj ){
        if(obj.hasOwnProperty(i)){
          newObj[i] = deepCopyMyself(obj[i],cloneObj) 
        }
      }
      return newObj;
    }

循环引用-----判断控制、原始类型》》》循环》》》遍历属性递归

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值