前端八股文面试(一)

106 阅读2分钟

前言

好记性不如烂笔头,今天看了B站的一些视频,就来做个简单的记录了,今天主要讲解得是三个小问题,希望对大家有用,如果觉得有用,请点小赞吧

问题1:假设后端返回给前台返回十万条数据,前端如何渲染呢

方式一:使用分页+settimeout

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>
<script>
    //需要插入的容器
    let ul = document.getElementById('container');
    // 插入十万条数据
    let total = 100000;
    // 一次插入 20 条
    let once = 20;
    //总页数
    let page = total/once
    //每条记录的索引
    let index = 0;
    //循环加载数据
    function loop(curTotal,curIndex){
        if(curTotal <= 0){
            return false;
        }
//每页多少条
        let pageCount = Math.min(curTotal , once);
        setTimeout(()=>{
            for(let i = 0; i < pageCount; i++){
                let li = document.createElement('li');
                li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
                ul.appendChild(li)
            }
            loop(curTotal - pageCount,curIndex + pageCount)
        },0)
    }
    loop(total,index);
</script>

方式二:使用requestAnimationFrame减少重排

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>
<script>
    //需要插入的容器
    let ul = document.getElementById('container');
    // 插入十万条数据
    let total = 100000;
    // 一次插入 20 条
    let once = 20;
    //总页数
    let page = total/once
    //每条记录的索引
    let index = 0;
    //循环加载数据
    function loop(curTotal,curIndex){
        if(curTotal <= 0){
            return false;
        }
//每页多少条
        let pageCount = Math.min(curTotal , once);
        window.requestAnimationFrame(function(){
            for(let i = 0; i < pageCount; i++){
                let li = document.createElement('li');
                li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
                ul.appendChild(li)
            }
            loop(curTotal - pageCount,curIndex + pageCount)
        })
    }
    loop(total,index);
</script>

方式三:使用文档碎片做一次性插入 代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>
<script>
    //需要插入的容器
    let ul = document.getElementById('container');
    // 插入十万条数据
    let total = 100000;
    // 一次插入 20 条
    let once = 20;
    //总页数
    let page = total/once
    //每条记录的索引
    let index = 0;
    //循环加载数据
    function loop(curTotal,curIndex){
        if(curTotal <= 0){
            return false;
        }
//每页多少条
        let pageCount = Math.min(curTotal , once);
        window.requestAnimationFrame(function(){
            let fragment = document.createDocumentFragment();
            for(let i = 0; i < pageCount; i++){
                let li = document.createElement('li');
                li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
                fragment.appendChild(li)
            }
            ul.appendChild(fragment)
            loop(curTotal - pageCount,curIndex + pageCount)
        })
    }
    loop(total,index);
</script>

问题2:v2中得data为什么是一个函数,v3为什么要使用return呢

其实无论是v2还是v3其中的自定义数据,都是要需要做为函数进行返回,不直接写死的原因是在于当组件复用时避免数据的污染,其实就是避免数据重复

举例1:当data是一个对象时

<script>
    let Test = function () {
        this.val = this.val
    }
    Test.prototype.val = {
        a:'1',
        b:'2'
    }
    var conponent1 = new Test()
    var conponent2 = new Test()
    conponent1.val.a = '6'
    console.log(conponent1); // a=12
    console.log(conponent2); // a=12
</script>

打印结果如下: image.png 可以看到,如果我们在直接使用对象时,当我们在改变对象的某一属性时,其他实例的属性值也会同步的发生改变。

举例2:当data是一个函数时

<script>
    function Test() {
        this.val = this.val()
    }
    Components.prototype.val = function () {
        return {
            a:'1',
            b:'2',
        }
    }
    var conponentA = new Components()
    var conponentB = new Components()
    conponentA.val.a = '6'
    console.log(conponentA); // a=6
    console.log(conponentB); // a=1
</script>

打印结果如下:

image.png

问题3:对象的原型

其实看到这句话的时候大家都知道答案了,我呢只不过是在这里多絮叨一下。

首先我们都知道,原型是函数特有的属性,普通的对象或者某一变量它是不具备原型的

其次是,原型链的终极是nul,这一点大家都是毋庸置疑的,原型的依次查找形成了一层原型链。

还有一点就是,原型的特点之一就是继承,儿子可以继承老子的特点,但是儿子也可以保留自己的特点。

一行代码证明对象无原型:

<script>
    let obj = {
        a: 1,
        b: 2
    }
    let test = function () {
        console.log(11);
    }
    test.prototype.a = 22;
    const res = new test();
    console.log(res)
    obj.prototype.c = 12;
    console.log(obj)
</script>

打印结果如下:

image.png

所以可以看出普通的对象是没有原型的,只有函数才会有原型