美文网首页
前端知识点之JS

前端知识点之JS

作者: 洛珎 | 来源:发表于2020-02-26 13:12 被阅读0次

    一、第一部分

    1.1值类型和引用类型

    1.1.1 image.png
    image.png

    值类型都是变量,通过在栈中进行存储,值类型在内存中所占的空间小;a=100,直接给a分配100的值空间;b=a,直接给b也分配一个100的值空间;因此a=200,直接修改a的值空间即为200;而b的值空间不变还是100


    image.png
    image.png
    引用类型在内存中所占空间较大,一般通过栈和堆进行存储,给a={age:20},会在堆中申请一个内存地址,指向这个对象{age:20},;也就是说,a中存储的并不是一个对象,而是一个内存地址1,这个内存地址1,指向这个对象。把b=a,b也就指向这个内存地址1,;当b.age=21,b就把这个内存地址1改成了指向对象{age:21}了;因此此时的内存地址1已经被改成指向对象{age:21};a.age打印为改变后的对象{age:21}。
    1..1.2 常见值类型
    image.png
    image.png

    注意:使用const声明变量时必须赋值,要不然会报错
    1.1.3常见引用类型


    image.png

    注意:函数也可当做一个特殊的类型

    1.2 typeof运算符和深拷贝

    1.2.1 typeof运算符

    注意:typeof可以判断所有的值类型


    image.png

    也可以判断 函数类型和引用类型


    image.png

    引用类型只能识别到对象‘object’,具体还得使用其他方法

    1.2.2 深拷贝

    1.2.2.1 先看下浅拷贝:


    image.png

    //shanghai
    也就是说上面的例子是符合引用类型的,改变了共同指向的内存地址指向的对象

    1.2.2.2 深拷贝:不改变原来内存地址指向的对象


    image.png
    image.png
    image.png

    先使用typeof判断obj是null还是(数组和对象)
    如果typeof obj是null不是(数组和对象),就返回obj;
    如果instanceof 判断是数组,就返回[];否则返回{};
    开始for循环遍历数组或者对象的每个值,要先hasOwnProperty过滤掉不是原型上的属性,保证key是obj自己本身 的属性,在对其属性进行一一深拷贝递归调用;
    返回所得结果result:


    image.png

    1.3 变量计算

    主要涉及到的有:字符串拼接、==、if语句和逻辑运算

    1.3.1 字符串拼接

    image.png

    1.3.2 == 运算符

    image.png
    image.png

    1.3.3 if语句和逻辑运算

    真变量:!!a === true 的变量;
    假变量:!!a ===false 的变量;


    image.png
    image.png

    假变量都有哪些?


    image.png
    image.png

    逻辑运算符


    image.png

    上面的例子:1.因为10是变量,所以继续看后面的,0 是假变量,所以返回0;
    2.' '是假变量,继续看后面,'abc'是真变量,返回'abc';

    改一下:
    1.console.log(0&&) ;
    //0
    因为0是假变量,直接返回0
    2.console.log('abc' || ' ') ;
    //'abc'因为'abc'是真变量,直接返回'abc'

    总结:
    1.typeof能判断哪些类型?
    答:1.识别所有值类型
    2.识别函数
    3.判断是否是引用类型
    2.==何时用?===何时用?
    答:除了判断==null之外,其他一律用===


    image.png

    3.值类型和引用类型的区别?
    面试中会出题,比如:


    image.png
    其中x1=obj1.x是干扰判断,值类型赋值,直接分配内存空间;obj2.x=101,引用类型赋值,改变了与obj1共同指向的内存地址指向的对象,修改为{x:101}
    4.手写深拷贝
    答:首先判断是值类型还是引用类型;再注意判断obj是数组还是对象;递归

    第二部分

    题目:

    1.如何精准判断一个变量是不是数组?
    2.手写一个简易 的jQuery,考虑插件和扩展性
    3.class的原型本质,怎么理解

    知识点

    1.class和继承
    2.类型判断instanceof
    3.原型和原型链

    2.1 class

    image.png

    2.2 继承

    extends、 super、扩展或重写


    image.png
    image.png

    2.3 类型判断-instanceof

    image.png

    通过instanceof判断引用类型,前者是否是后者class构建出来的;或者说后者class是前者class构建出来的父类。
    注意:Object是所有类的父类

    2.4 原型

    .prototype叫显式原型

    _proto _叫隐式原型

    image.png
    image.png
    原型关系:

    1.每个class都有显式原型prototype
    2.每个实例都有隐式原型_proto _
    3.实例的_proto _指向对应class的prototype


    image.png

    基于原型的执行规则:

    1.获取属性xiaoluo.name或执行方法xialuo.sayHi()
    2.先在自身属性和方法上寻找
    3.如果找不到则自动去_proto _中查找

    2.5 原型链

    image.png

    再看instanceof
    可以顺着xialuo能否对应到class的原型上的显式原型上;
    比如,xialuo instanceof Studnet可以找到对应的显式原型Student.prototype;Student instanceof People可以找到对应的显式原型People.prototype;People instanceof Object可以找到对应的显式原型Object.prototype;

    问题:

    1.如何准确判断一个变量是不是数组?
    答:使用instanceof,结合原型链图理解

    2.手写一个简易的j Query,考虑插件和扩展性
    答:
    3.class的原型本质,怎么理解?
    答:
    1.原型和原型链的图示
    2.属性和方法的执行规则

    小结:

    1.class和继承,结合上面手写jQuery的示例来理解
    2.instanceof
    3.原型和原型链:图示和执行规则

    第三部分

    题目:

    1.this不同的使用场景
    2.手写bind函数
    3.实际开发中闭包的应用场景,举例
    4.场景题:创建10个a标签,点击时候弹出对应的序号

    知识点

    作用域和自由变量、闭包、this

    作用域

    image.png

    作用域分为:全局作用域、函数作用域、块级作用域

    3.1作用域:

    image.png

    自由变量:一个变量在当前作用域没有被定义,但被使用了,那怎么办?可以向上级作用域,一层一层一次查找,直到找到为止,如果到全局作用域都还没找到,则报错 xx is not defined

    3.2 闭包:

    作用域应用的特殊情况,有两种表现:1.函数作为参数被传递2.函数作为返回值被返回

    注:所有自由变量的查找,是在函数定义的地方,向上级作用域查找,而不是在执行的地方查找
    image.png

    因为fn()执行时,执行 create函数,create函数里面返回匿名函数打印a值,a值在匿名函数中没有找到,想上级 create函数查找a,找到了,a为100,因此打印a为100


    image.png

    因为执行print(fn)时,执行print函数,print函数里面执行fn(),执行fn()则执行fn函数,打印a值,a在fn函数中没有找到,向上级全局查找,找到了,a为100,则打印a为100

    3.3 this

    注意:this的取值是在函数执行的时候被调用,而不是在定义的时候

    应用场景:作为普通函数被调用、使用call 、apply、bind被、作为对象方法被调用、在class方法中调用、箭头函数中

    eg1: image.png
    因为fn1()执行,打印的this是去全局的,所以fn1()执行打印window;而执行fn1.call(),call里面可以改变this指向,里面传入了对象{x:100},所以打印的就是这个对象{x:100};而执行fn2(),bind里面也可以改变this指向,里面传入了对象{x:200},就打印这个对象{x:200},注意一点,bind有条件:需要返回一个新的函数fn2,执行这个新函数才可以使用,而call直接调用就可以使用

    eg2:


    image.png
    因为sayHi()作为zhangsan的sayHi()方法被执行,使以返回这个对象;而下面的wait()里面有一个setTimeout()执行,也就是说执行zhangsan.wait()时,如果没有setTimeout(),就返回的是zhangsan这个对象,有setTimeout()就相当于作为一个普通函数被执行,而不是作为一个方法被执行,是setTimeout本身触发的执行,而不是zhangsan,因此,打印的是this是window
    eg3:
    image.png
    这个跟上面那个唯一不同的是setTimeout()里面有个箭头函数()=>{},而箭头函数的this是取它的上级作用域的值,因此跟zhangsan.waitAgain()方法跟zhangsan.sayHi()方法一样,取得是zhangsan这个对象

    eg3:


    image.png
    constructor里面的this代表的是创建的实例,sayHi()方法里面的this代表就是zhangsan对象

    题目解答:

    1.this不同的使用场景
    答:1、当做普通函数被调用 2.使用call、apply、bind 3.作为对象方法调用 4.在class的方法中调用 5.箭头函数
    2.手写bind函数
    答:


    image.png
    image.png

    3.实际开发中闭包的应用场景,举例


    image.png

    //100
    4.场景题:创建10个a标签,点击时候弹出对应的序号


    image.png
    因为i是全局变量,而
    a.addEventListener('click', function(e){

    e.preventDefault()
    alert(i)
    })
    事件是当点击才会触发该事件,所以for循环非常快早已遍历到10,因此每当点击事件发生前,i就是10,因此点击0-10,都弹出10

    修改:


    image.png

    将i改成局部变量,使其在for循环块级作用域里面,每次for循环的时候就会形成一个块,每次的值都会不一样

    4.异步

    题目:

    1.同步和异步的区别是什么?
    2.手写用Promise加载一张图片
    3.前端使用异步的场景有哪些?

    知识点

    1.单线程和异步
    2.应用场景
    3.callback hell 回调地域和Promise

    4.1 单线程和异步

    1. js是单线程语言,只能同时做一件事
      2.浏览器和node.js已支持js启动进程,如web worker
      3.js和DOM渲染共用一个线程,因为Js可修改DOM结构
      4.遇到等待(网络请求,定时任务)不能卡住,需要异步,回调cakkback函数
      例子1:
      异步:
      先执行同步的100,遇到等待一秒才执行的setTimeout函数,但异步不会阻塞后面300的执行,因此先100,再300,再等待1秒执行200


      image.png

      // 100 300 200
      例子2.
      同步:会阻塞代码的执行,alert()没有完成,后面的就没法执行


      image.png
      //先100,弹出200警告框,点击确认之后才会打印300

    4.2应用场景

    1.网络请求,如ajax场景


    image.png
    image.png

    2.定时任务,如setTimeout定时器


    image.png
    image.png

    4.3回调地域 callback hell

    image.png

    4.3 Promise

    image.png

    问题:


    image.png

    4.4 手写promise加载图片示例

    eg1:加载一张图片


    image.png
    image.png

    eg2:加载多张图片


    image.png

    4.5异步应用场景

    1.网络请求,如ajax图片加载
    2.定时任务,如setTimeout

    image.png

    先1,遇到等待1秒执行的setTimeout异步不会阻塞后面代码,打印3,再遇到等待0秒,也就是立即执行的的setTimeout异步,但依然是异步,因此还是执行后面的代码5,然后再执行立即等待的4,然后再是2

    小结

    1.单线程和异步,异步和同步的区别
    2.前端异步的应用场景:网络请求&定时任务
    3.Promise解决callback hell嵌套的问题

    js基础总结

    内容:
    1.变量的类型和计算
    2.原型和原型链
    3.作用域和闭包
    4.异步和单线程
    题目:
    1.typeof能判断哪些类型
    2.何时使用===何时使用==
    3.值类型和引用类型的区别
    4.手写深拷贝
    知识点:
    1.值类型 VS 引用类型,堆栈模型,深拷贝
    2.typeof运算符
    3.类型转换,truly和falsely变量
    原型和原型链题目:
    1.如何准确判断一个变量是不是数组?
    2.手写一个简易 的 jQuery,考虑插件和扩展性
    3.class的原型本质,怎么理解
    原型和原型链-知识点
    1.class和继承,结合手写jquery的示例来理解
    2.instanceof
    3.原型和原型链:图示
    4.this的不同应用场景,如何取值?
    5.手写bind函数
    6.实际开发遇到的闭包问题(0-10对应弹出)
    作用域和闭包-知识点
    1.作用域和自由变量
    2.闭包:两种常见方式
    &自由变量查找规则
    3.this
    4.异步同步区别?
    5.手写promise加载图片
    6.前端使用异步场景
    异步和单线程-知识点:
    1.单线程和异步,异步和同步的区别
    2.前端异步的应用场景:网络请求&定时任务
    3.promise解决callback hell

    第四部分 JS Web API

    1.DOM

    DOM操作

    题目:

    1.DOM是那种数据结构?
    2.DOM操作的常用API?
    3.attr和property的区别?
    4.一次性插入多个DOM节点,考虑性能?

    知识点

    1.DOM本质

    html解析出来的一棵树


    image.png
    image.png

    2.DOM节点操作

    先是获取DOM节点,再attribute,property
    获取dom节点?


    image.png

    1.通过getElementById获取;
    2.通过getElementsByTagName获取;
    3.通过getElementsByClassName获取;
    4.通过querySelectorAll获取;


    image.png image.png

    dom节点的property:


    image.png image.png
    dom节点的attr:
    image.png
    image.png
    总结:
    propertyattribute区别:
    property:修改对象属性,不会体现到html结构中;
    attribute:修改html``属性,会改变html结构,两者都有可能引起DOM重新渲染,建议尽量用property`

    3.DOM结构操作

    3.1新增/插入节点
    新增


    image.png image.png

    移动


    image.png
    image.png

    3.2获取子元素列表,获取父元素
    获取子元素列表:
    const div1 = document.getElementById('div1')
    const child = div1.childNodes
    获取父元素
    const div1 = document.getElementById('div1')
    const parent = div1.parentNode

    image.png image.png

    获取对应文本text节点:


    image.png
    image.png

    3.3删除子元素
    通过removeChild:
    div1.removeChild(child[0])

    4.DOM性能

    4.1DOM操作占用cpu较多,应避免频繁的DOM操作
    4.2对DOM查询做缓存
    4.3 将频繁操作改为一次性操作

    DOM查询做缓存

    //不缓存DOM查询结果
    for(let i=0;i<document.getElementByTagName('p').length;i++){
    //每次循环,都会计算length,频繁进行DOM查询
    }
    缓存DOM查询结果
    const pList=document.getElementsByTagName('p');
    const length=pList.length
    for(let i =0;i<length;i++){
    //缓存length,只进行一次DOM查询
    }
    将频繁操作改为一次性操作
    const listNode =document.getElementById('list')

    //创建一个文档片段,此时还没有插入到DOM书中
    const frag = document.createDocumentFragment();
    //执行插入
    for(let x = 0;x < 10; x++){
    const li = document.createElement("li");
    li.innerHTML ="list item" + x
    frag.appendChild(li)
    }
    //都完成之后,再插入到DOM树中
    listNode.appendChild(frag)

    image.png
    image.png
    总结

    1.DOM是那种数据结构?
    答:树(DOM树)
    2.DOM操作的常用API?
    答:DOM节点操作和DOM结构操作、attribute和property
    3.attr和property的区别?
    答:attribute是修改html结构,会改变HTML结构;property是修改对象属性,不会体现到html结构中;两者都有可能引起DOM重新渲染
    4.一次性插入多个DOM节点,考虑性能?
    答:通过frag文档片段,要考虑到先缓存再一起插入

    2.BOM

    题目:
    1.如何识别浏览器的类型
    2.分析拆解url各个部分

    知识点
    navigatior和screen

    通过navigatior.userAgent来查看浏览器信息

    image.png
    image.png

    通过screen查看屏幕信息:

    image.png
    image.png
    location

    location.href:网址
    location.protocol:协议
    location.host:域名
    location.pathname:获取待path路径
    location.search:获取常用参数
    location.hash:#后面的内容

    image.png
    image.png
    image.png
    history

    history.back():程序后退
    'hiotory.forward()':程序前进

    3.事件绑定

    题目:
    1.编写一个通用事件监听函数
    2.描述事件冒泡的流程
    3.无限下拉的图片列表,如何监听每个图片的点击?
    知识点:
    3.1 事件绑定
    const btn=document.getElementById('btn1');
    btn.addEventListener('click',event=>{ console.log('clicked')})

    image.png image.png

    event.target:获取触发的元素;
    event.preventDefault() :阻止默认行为


    image.png
    3.2事件冒泡
    image.png image.png
    image.png

    点击激活,触发p1点击事件,打印出“激活 取消”
    因为p1>div1>body,先是p1事件打印“激活”,再冒泡到body,触发body的点击事件,打印“取消”

    加上阻止冒泡e.stopPropagation()

    image.png
    image.png

    3.3事件代理

    优点:代码简洁;减少浏览器内存占用(子元素较多需要设置监听时,只需要在父元素上设置一次即可)

    image.png
    image.png
    image.png
    注意:有了event.preventDefault()阻止默认事件,点击某个<a href="#">a2</a>就不会跳转到#页面

    3.4 编写一个通用的事件监听函数?注意this指向

    image.png
    image.png
    描述事件冒泡的流程?

    答:
    1.基于DOM树形结构
    2.事件会顺着触发元素向上冒泡3.应用场景:代理

    无限下拉图片列表,如何监听每个图片的点击?

    答:
    1.利用事件代理;
    2.用e.target获取触发元素
    3.用matches来判断是否是触发元素

    4.ajax

    题目:
    1.手写一个简易的ajax
    2.跨域的常用实现方式

    知识点:
    1.XMLHttpRequest
    2.状态码
    3.跨域:同源策略、跨域解决方案

    4.1XMLHttpRequest
    image.png image.png

    在ajacx文件夹下的XMLHttpRequest文件夹下新建data文件夹,data文件夹下面再新建test.json;

    image.png
    访问http://127.0.0.1:5500/ajax/XMLHttpRequest/data/test.json
    image.png
    image.png
    实现get请求:
    访问http://127.0.0.1:5500/ajax/XMLHttpRequest/index.html
    image.png

    那么,POST请求:效果无法演示,代码如下:


    image.png

    0-(未初始化)还没有调用send()方法;
    1-(载入)已调用send()方法,正在发送请求
    2-(载入完成)send()方法执行完成,已经接收到全部响应内容
    3-(交互)正在解析响应内容
    4-(完成)响应内容解析完成,可以在客户端调用

    xhr.staus

    2xx-表示成功处理请求,如200;
    3xx-需要重定向,浏览器直接跳转,如301 302 304;(301永久重定向,302临时重定向,304资源未被改变)
    4xx-客户端请求错误,如404 403 (404 没有找到;403没有访问权限)
    5xx-服务端错误(服务器程序有bug)

    4.2 跨域
    4.2.1什么是跨域?

    1.ajax请求时,浏览器要求当前网页和server必须同源(安全)
    2.同源:协议、域名、端口,三者必须一致
    比如:
    前端 :http://a.com:8080/;
    后端:https://b.com/api/xxx;

    4.2.2 加载图片css js可无视同源策略

    1.<img src=跨域的图片地址/>
    2.<link href=跨域的css地址/>
    3.<script src=跨域的js地址></script>
    4.<img /> 可用于统计大点,可使用第三方统计服务
    5.<link /><script>可使用CDN,CDN一般都是外域
    6.<script>可实现JSONP
    注意:所有的跨域,都必须经过server端允许和配合;未经server端允许就实现跨域,说明浏览器有漏洞,危险信号

    4.3JSONP

    1.访问https://taobao.com,服务端一定会返回一个html文件吗?
    答:不一定,服务端可以任意动态拼接数据返回,只要符合html格式要求;同理于<script src="https://taobao.com/getData.js" >
    因此,<script>可绕过跨域限制,服务端可以任意动态拼接数据返回;<script>就可以获得跨域的数据,只要服务端愿意返回

    image.png
    image.png
    <script>标签加上username=xxx
    image.png
    image.png
    image.png

    改变callback函数


    image.png
    image.png
    image.png
    jQuery实现jsonp
    image.png
    CORS-服务端设置http-header

    解答:
    1.手写ajax?
    答:


    image.png
    image.png
    image.png

    2.jQuery完整版ajax


    image.png
    补充

    1.fetch
    [https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch](https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch)

    image.png
    image.png
    2.axios
    image.png

    执行get请求:


    image.png

    执行post请求:


    image.png
    执行多个请求:
    image.png
    axios API:
    image.png

    5.存储

    题目:
    描述cookie、localStorage、sessionStorsge区别?
    知识点:

    cookie

    本身用于浏览器和server通讯,被“借用”到本地存储来,可用document.cookie="xxxx"来修改。
    缺点:存储大小,最大4kb;http请求时需要发送到服务端,增加请求数据量;只能用document.cookie="xxxx"来修改,太过简陋

    localStorage和sessionStorage

    两个都是HTML5专门为存储而设计,最大可存5M;API简单易用:setItem和getItem;不会随着http请求被发送出去
    localStorage和sessionStorage的区别?

    1.localStorage数据会永久存储,除非代码或手动删除
    2.sessionStorage数据只存在于当前会话,浏览器关闭则清空
    3.一般用localStorage会更多一些


    image.png image.png
    描述cookie、localStorage、sessionStorsge区别?
    答:
    1.容量:cookie是4kb容量,localStorage和sessionStorsge是5M容量
    2.api易用性:cookie用document.cookie="xxxx"来修改,太过简陋;localStorage和sessionStorsge使用setItem和getItem
    3.是否跟随http请求发送出去:localStorage和sessionStorsge不会随着http请求被发送出去,因此在客户端(浏览区);而cookie是会随着HTTP请求被发送出去,值服务端
    4.数据上的生命周期的不同:
    Cookie 一般由服务器生成,可设置失效时间,如果在浏览器端生成cookie,默认是关闭后失效。

    localStorage 除非被永久清除,否则永久保存。
    sessionStorage 仅在当前会话会有效,关闭页面或浏览器后被清除

    第五部分 开发环境

    1.git

    1.1常用git命令:
    答:
    (1)git add:把文件添加到git;
    (2)git checkout xxx:如果发现修改错误,想还原到以前的状态;
    (3)git commit -m "xxx":提交一行记录;
    (4)git push origin master:推送到服务端
    (5)git pull origin master:从服务端下载
    (6)git branch:开分支
    (7)git checkout -b xxx/git checkout xxx:切换分支
    (8)git merge xxx:合并分支

    2.调试工具
    image.png
    3.抓包

    是移动端h5页,查看网络请求,需要用工具抓包,windows一般用fidder,Mac OS一般用charles。
    抓包过程:
    手机和电脑连同一个局域网,将手机道里道电脑上,
    手机浏览网页,抓包;查看网络请求,网址代理,https

    4.webpack
    5.linux命令

    ls 查看文件夹;clear清除;ll查看列表

    第六部分 运行环境

    1.网页是怎么加载的?
    2.性能优化?
    3.安全?
    题目:
    1.从输入url到渲染出页面的整个过程
    2.window.onloadDOMContentLoaded的区别
    知识点
    1.加载资源的形式
    2.加载资源的过程
    3.渲染页面的过程

    6.1.页面加载和渲染

    6.1.1加载资源的形式有哪些
    要加载:
    (1)html代码
    (2)媒体文件,如图片、视频等;
    (3)javascriptcss

    6.1.2.加载过程

    (1)首先DNS解析:域名->IP地址
    (2)浏览器根据IP地址向服务器发起http请求
    (3)服务器处理http请求,并返回浏览器

    6.1.3.渲染过程

    (1)根据HTML代码生成DOM Tree
    (2)根据CSS代码生成CSSOM
    (3)将DOM Tree和CSSOM整合行程 Render Tree

    (4)根据Render Tree渲染页面
    (5)遇到<script>则暂停渲染,优先加载并执行JS代码,完成再继续
    (6)直至把Render Tree渲染完成

    示例:
    image.png

    根据html生成DOM树,根据CSS代码生成CSSOM,再将DOM Tree和CSSOM整合行程 Render Tree进行渲染;因为无css,所以渲染比较快

    image.png
    image.png

    根据html生成DOM树,根据CSS代码生成CSSOM,再将DOM Tree和CSSOM整合行程 Render Tree进行渲染

    思考:为何把css放在head中?

    答:避免重复渲染;因为如果放在body里面的最后,前面html解析生成dom树,无css,因此不生成cssom,等整合render树渲染后又发现body下面的css,发起css解析生成cssdom,再render树解析,这样就重复了render树解析渲染
    3.

    image.png
    image.png
    加载过程:首先html解析生成dom树,渲染出default;遇到<script>标签要暂停渲染,优先加载<script>的js代码,将内容改成update by js;然后再继续解析html代码,渲染p标签
    思考:为何建议把js放到body最后?

    答:示例2是为了讲解知识点,实际开发js位置不是很合理,应该把js代码放到body最后。因为示例2会导致渲染的时间过长,先是渲染出dom树,遇到script优先加载js代码后,又dom渲染了一遍,这样渲染的时间过长;应该把js代码放到body最后,把html渲染完后再执行script的渲染。

    4. image.png
    加载过程:首先解析html生成dom树,渲染出test,遇到img标签,这个不像script,不会阻塞dom渲染,一遍渲染img,一般继续dom渲染,可能图片比较大,渲染时间较长,会先空着,继续渲染下面的test,等img渲染完成,填充即可
    6.1.4.window.onloadDOMContetLoaded区别

    答:window.addEventListener('load',function (){ }):页面的全部资源加载完才会执行,包括图片、视频
    document.addEventListener('DOMContentLoaded',function(){ }):DOM渲染完即可执行,此时图片、视频可能还没加载完。

    一般监听DOMContetLoaded,不用等到图片加载完,加载完dom即可
    eg:

    image.png
    image.png
    image.png
    图片较大还没加载完,dom已渲染完成,所有资源渲染完之后然后再是winow loader;多个图片的话,会按照实际的图片加载速度
    6.2 性能优化

    性能优化原则:
    1.多使用内存、缓存或其他方法
    2.减少CPU计算量,减少网络加载耗时
    3.适用于所有编程的性能优化-空间换时间

    如何入手?
    1.让加载更快:
    1.1减少资源体积:压缩代码(比如做webpack时,在生产环境下打包,代码体积会比在开发环境打包更小)
    1.2 减少访问次数:合并代码(比如雪碧图),SSR服务端渲染(服务端把页面以及显示内容一起渲染,不用前端通过ajax发送请求再返回数据渲染),缓存(比如有10个资源,不用缓存需要访问10次,用了缓存访问一次即可)
    1.3使用更快的网络:CDN
    2.让渲染更快:
    2.1 CSS放在head,Js放在body最下面
    2.2 尽早开始执行Js,用DOMContentLoaded触发
    2.3 懒加载(图片懒加载,上滑加载更多)
    2.4 对DOM查询进行缓存(DOM操作比较耗费性能,需要进行缓存)
    2.5 频繁DOM操作,合并到一起插入DOM结构
    2.6 节流throttle、防抖debounce
    解释:
    1.资源合并

    image.png
    2.缓存
    image.png
    静态资源加hash后缀,根据文件内容计算hash;
    文件内容不变,则hash不变,url不变;url和文件不变,则会自动触发http缓存机制,返回304
    bundle.[contenthash].js文件变hash变,文件不变hash不变。比如上线一个新功能,代码中包括老内容和新内容,只有一个文件是新内容,那么老文件url和文件不变,会触发http缓存机制,返回304;新文件会计算新的hash新的url,自动下载。我们希望不变的触发缓存,变的重新计算下载

    3.CDN
    CDN是专门做静态文件的服务,也满足缓存的304机制
    4.SSR
    1.服务端渲染:将网页和数据一起加载,一起渲染
    2.非SSR(前后端分离):先加载数据,再渲染数据
    3.早先JSP、ASP、PHP都是,现在的vue、react SSR
    5.懒加载


    image.png

    说明:比如新闻列表,我们希望图片不是一下子加载完,而是首先显示第一屏的图片,再是随着向上滑动,图片逐渐显示完。

    abc.png是图片真实地址,当页面有10张图片,第一屏有5张图片,显示的是体积较小的预览图片preview.png,随着向上滑动(可由dom节点距离屏幕顶部top的值判断),再将图片真实地址赋值给dom节点

    6.缓存DOM查询
    不缓存dom查询结果



    缓存dom查询结果


    image.png

    7.多个dom操作一起插入到dom结构

    image.png
    8.尽早开始js执行
    window.addEventListener('load',function (){ }):页面的全部资源加载完才会执行,包括图片、视频
    document.addEventListener('DOMContentLoaded',function(){ }):DOM渲染完即可执行,此时图片、视频可能还没加载完。
    6.3 防抖和节流
    6.3.1 防抖debounce

    监听一个输入框时,文字变化后触发change事件

    直接用keyup事件,则会频繁触发change事件

    防抖:用户输入结束或暂停时,才会触发change事件
    机制原理:设置一个定时器,当定时器为空时,触发异步请求再请空,

    image.png
    比如输入‘12’;开始timer初始化为null,触发keyup监听事件,执行setTimeout()异步请求,5秒还没到,已输入2,触发监听事件,此时timer是有值的,timer有值,执行clearTimerout(timer),清除了1的定时任务异步操作不打印,重新设置一个2的定时任务,等5秒到打印,timer重置null。

    那么,封装一下:


    image.png
    6.3.2 节流

    拖拽一个元素时,要随时拿到钙元素被拖拽的位置;

    直接用drag事件,则会频繁触发,很容易导致卡顿

    节流:无论拖拽速度多快,都会每隔100ms触发一次


    image.png
    image.png

    封装一下:


    image.png
    image.png
    6.4 安全

    问题:常见的web前端攻击方式有哪些?

    6.4.1 安全-xss攻击

    示例:一个博客网站,我发表了一篇博客,其中嵌入<script>脚本,脚本内容是获取cookie,发送到我的服务器(服务器配合跨域),当发布了这篇博客,有人查看它,我就可以轻松收割访问者的cookie


    image.png

    这样访问者的信息就可以被获取到,可以通过跨域ajax等方式传到对方服务器


    image.png
    那么怎么预防?
    6.4.2 xss预防

    替换特殊字符,如<变为&lt;>变为&gt;

    <script>变为&lt;script&gt;直接显示,而不会作为脚本运行;

    前端要替换,后端也要替换,都做总不会有错


    image.png

    这样会作为字符串被解析,而不会被运行

    6.4.3 XSRF攻击

    示例:小明正在网上购物,看中了某个商品,商品id是100.付费接口是xxx.com/pay?id=100,但没有任何验证;小王是攻击者,看重另外一个商品,id是200;那么小王向小明发送一封电子邮件,标题很吸引人,比如中奖了,但邮件正文隐藏着<img src=xxx.com.pay?id=200 />,小明已查看邮件,就帮小王买了id是200的商品。

    XSRF预防?
    1.使用post接口
    2.增加验证:比如密码,短信验证码、指纹验证等。

    面试题

    1.var 和let const区别?

    答:
    var是es5语法,let、const是es6语法,var有变量提升;
    var和let是变量,可修改;const是常量,不可修改;
    let const有块级作用域(外面访问不到),var没有

    2.typeof能判断哪些类型?

    答:

    1. 值类型:undefined``number,string,boolean,symbol
    2. 引用类型:object(注意,typeof null === 'object')
    3. function
    3.列举强制类型转换和隐式类型转换

    答:
    强制:parseIntparseFloattoString等;

    隐式:if、逻辑运算、==、+拼接字符串

    4.手写深度比较,模拟lodash isEqual

    答:


    image.png
    image.png
    image.png
    image.png
    5.split()join()的区别

    答:
    '1-2-3'.split('-') //[1,2,3];
    [1,2,3].join('-') //'1-2-3'

    6.数组的poppushunshiftshift分别做什么?

    答:
    功能是什么?
    返回值是什么?
    是否会对原数组造成影响?
    [图片上传失败...(image-8a369d-1583225059539)]

    【扩展】数组的api,有哪些是纯函数?
    答:纯函数:1.不改变原数组(副作用),2.返回一个数组
    concat:
    const arr1 = arr.concat([50,60,70])

    map:
    const arr2 = arr.map(num =>num*10)

    filter:
    const arr3 = arr.filter(num =>num >25)

    slice:
    const arr4 = arr.slice()

    非纯函数:
    psuh、pop shift、 unshift;
    forEach;
    some every;
    reduce;

    7.数组slice和splice区别

    答:

    1. 功能区别(slice 切片,splice剪接)
    2. 参数和返回值
    3. 是否纯函数?


      image.png
      image.png
    8.[10,20,30]map(parseInt)?

    答:这里说的很清楚
    https://blog.csdn.net/willard_cui/article/details/81504782
    当忽略参数 radix , JavaScript 默认数字的基数如下:

    如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
    如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
    如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。

    image.png
    9.ajax请求get和post区别?

    答:1)get一般用于查询操作,post一般用于提交操作;
    2)get参数拼接在url上,post放在请求体内(数据体积可更大);
    3)安全性:post易于防止CSRF

    10.函数call和apply的区别?

    答:传参方式不同:
    call是零散的传参方式,apply是以数组的形式
    fn.call(this,p1,p2,p3);
    fn.apply(this,arguments);

    11.事件代理(委托)是什么?

    答:


    image.png
    12.闭包是什么?有何特性?有何影响?

    答:
    1)回顾作用域和自由变量
    2) 回顾闭包应用场景:作为参数被传入,作为返回值被返回;
    3) 回顾:自由变量的查找,要再函数定义的地方(不是执行的地方)
    4)影响:变量会常驻内存,得不到释放。闭包不要乱用
    例1:

    image.png
    程序执行完return a=a1+a2+a3;a3、a2、a1、a被逐层释放
    例2:
    闭包,函数作为返回值:
    image.png
    闭包例子中的 a=100不能被释放,因为作为返回值了
    下面的a =200可以释放
    例3:
    闭包,函数作为参数:
    image.png
    a=100不能被释放,a=200可以被释放
    13.如何阻止事件冒泡和默认行为?

    答:阻止事件冒泡:event.stopPropagation()阻止默认行为:event.preventDefault()

    14.查找、添加、删除、移动DOM节点的方法?
    image.png

    答:

    15.如何减少DOM操作?

    1)缓存DOM查询结果(比如查询dom的list,可以先把list查出来保存,不要每次用再去查dom);
    2)多次DOM操作,合并到一次插入(比如文档片段片段)

    16.解释jsonp原理,为何不是真正的ajax

    答:ajax是通过XMLHttpRequest实现,jsonp是通过javascript标签实现;
    1)浏览器的同源策略(服务端没有同源策略)和跨域
    2)哪些html标签能绕过跨域?
    3)jsonp原理

    image.png
    定义一个全局函数,访问一个js文件,返回数据
    17.document.load和read的区别?
    答: image.png
    18.==和===区别?

    答:
    1)==会尝试类型转换
    2)=== 严格相等
    3)==使用场景?在==null时,其他都有===

    19.函数声明和函数表达式的区别?

    答:
    函数声明:function fn(){};
    函数表达式:const fn = function(){};
    函数声明会在代码执行前预加载,(相当于变量提升),而函数表达式不会
    函数声明:

    image.png
    //30
    函数表达式:
    image.png
    image.png
    因为是var sum,存在变量提升,没有被赋值,所以是undefined;但不是function
    20.new Object()和Object.create()的区别?

    答:
    首先,{}等同于new Object(),原型Object.prototype;
    其次,Object.create(null)没有原型;Object.create({...})可指定原型


    image.png
    image.png image.png image.png
    21.this场景?
    image.png

    //1
    //undefined

    22.关于作用域和自由变量的场景题?
    答: image.png
    23.判断字符串以字母开头,后面字母数字下划线,长度6-30

    答:const reg=/^[a-zA-Z]\w{5,29}$/

    image.png

    小写英文字母:/^[a-z]+$/

    英文字母:/^[a-zA-Z]+$/

    日期格式 2019-12-1 (\d表示查找数字):/^\d{4}-/d{1,2}-\d{1,2}$/

    用户名(\w 元字符用于查找单词字符,单词字符包括:a-z、A-Z、0-9,以及下划线, 包含 _ (下划线) 字符):/^[a-zA-Z]\w{5,17}$/

    简单的IP地址匹配 127.0.0.1(\d表示查找数字):/\d+\.\d+\.\d+\.\d+/

    24.关于作用域和自由变量的场景题?

    答:


    image.png
    25.手写字符串trim保证浏览器兼容性

    答:


    image.png
    25.获取多个数字中的最大值

    答:


    image.png
    image.png
    26.如何用js继承?

    答:
    1.class继承
    2.prototype继承

    27.如何捕获js中的异常?

    答:
    高风险处:


    image.png

    其他地方:


    image.png
    27.什么是JSON?

    答:1.json是一种数据格式,本质是一段字符串;
    2.json格式和js对象结构一致,对js语言更友好
    3.window.JSON是一个全局对象:JSON.stringify(对象转化成字符串)和JSON.parse(字符串转化成对象)
    //json里面不能用单引号


    28.获取当前页面url参数

    答:1.传统方式:查找location.search

    image.png
    image.png

    2.新api:URLSearchParams

    image.png
    29.将url参数解析为js对象

    答:1.传统


    image.png

    2.新api:


    image.png
    30.手写数组flatern,考虑多层级

    答:1.递归

    image.png
    2.reduce
    image.png
    3.toString & split
    image.png
    4.join & split
    image.png
    5.es6扩展运算符
    [].concat(...[1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5]
    image.png
    image.png
    31.数组去重

    答:
    1.传统方式:遍历元素逐个比较,去重


    2.set(无序,不能重复),效率高


    image.png
    32.手写深拷贝
    image.png

    注意:Object.assign不是深拷贝,是浅层的

    image.png
    image.png image.png
    image.png

    因此,注意Object.assign是浅拷贝

    33.介绍RAF requestAnimationFrame

    答:
    1.要想动画流畅,更新频率要60帧/s,即16.67ms更新一次视图
    2.setTimeout要手动控制频率,而RAF浏览器会自动控制
    3.后台标签或隐藏iframe中,RAF会暂停,而setTimeout依然执行

    代码演示:


    image.png

    1.用setTimeout方法:时间需要自己计算控制

    image.png
    2.用requestAnimationFrame方法,无需自己控制时间,推荐
    image.png
    image.png
    如何性能优化,从哪几方面考虑?

    答:1.原则:多使用内存、缓存、减少计算、减少网络请求
    2.方向:加载页面,页面渲染,页面操作流畅度

    相关文章

      网友评论

          本文标题:前端知识点之JS

          本文链接:https://www.haomeiwen.com/subject/wvugactx.html