前端知识点之JS

一、第一部分

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. 在请求地址中添加takon验证

CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
这种方法要比检查 Referer 要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对。

面试题

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.方向:加载页面,页面渲染,页面操作流畅度

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容