补缺
C#、Java一样JavaScript有自动垃圾回收机制,JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是时时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。
标记清除
这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。至于怎么标记有很多种方式,比如特殊位的反转、维护一个列表等,这些并不重要,重要的是使用什么策略,原则上讲不能够释放进入环境的变量所占的内存,它们随时可能会被调用的到。
垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了,因为环境中的变量已经无法访问到这些变量了,然后垃圾回收器相会这些带有标记的变量机器所占空间。
引用计数法
引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减1。当这个值的引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾回收器下次再运行时,它就会释放那些引用次数为0的值所占用的内存。
造成跨域的原因和解决方法
浏览器的同源策略是浏览器上为安全性考虑实施的非常重要的安全策略。
从一个域上加载的脚本不允许访问另外一个域的文档属性。
举个例子:比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),
如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。
何谓同源:URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示它们同源。
在浏览器中,<script>、<img>、<iframe>、<link>等标签都可以加载跨域资源,而不受同源限制,
但浏览器会限制脚本中发起的跨域请求。比如,使用
XMLHttpRequest 对象和Fetch发起 HTTP 请求就必须遵守同源策略。
Web 应用程序通过
XMLHttpRequest 对象或Fetch能且只能向同域名的资源发起 HTTP 请求,而不能向任何其它域名发起请求。
不允许跨域访问并非是浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。
最好的例子是CSRF跨站攻击原理,请求是发送到了后端服务器,无论是否设置允许跨域,
有些浏览器不允许从HTTPS跨域访问HTTP,比如Chrome和Firefox,这些浏览器在请求还未发出的时候就会拦截请求,这是特例。
克服跨域限制的方法有(实践中后两种最常用,所以重点介绍):
(1)通过jsonp跨域
(2)通过修改document.domain来跨子域
(3)使用window.name来进行跨域
(4)使用HTML5中新引进的window.postMessage方法来跨域传送数据
(5)使用代理服务器,使用代理方式跨域更加直接,因为同源限制是浏览器实现的。如果请求不是从浏览器发起的,就不存在跨域问题了。
使用本方法跨域步骤如下:
1. 把访问其它域的请求替换为本域的请求
2. 服务器端的动态脚本负责将本域的请求转发成实际的请求
为了通过Ajax从http://localhost:8080访问http://localhost:8081/api,可以将请求发往http://localhost:8080/api。
然后利用Apache
Web服务器的Reverse
Proxy功能做如下配置:ProxyPass
/api http://localhost:8081/api
(6)CORS全称是"跨域资源共享"(Cross-origin
resource sharing),CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能
(IE浏览器不能低于IE10),因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
浏览器将CORS请求分成两类:简单请求(simple
request)和非简单请求(not-so-simple
request)
(1) 请求方法是以下三种方法之一:HEAD
GET POST
(2)HTTP的头信息不超出以下几种字段:Accept
Accept-Language Content-Language Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
对于简单请求,浏览器在发出CORS请求时会在头信息之中增加一个Origin字段。服务器的返回会多出3个字段:
Access-Control-Allow-Origin(必须)
允许跨域的源
Access-Control-Allow-Credentials(可选) 表示是否允许发送Cookie。默认情况下,Cookie可以包含在请求中,一起发给服务器
如果服务器不需要浏览器发送Cookie,删除该字段即可。
Access-Control-Expose-Headers(可选)
CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:
Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,
就必须在Access-Control-Expose-Headers里面指定。如指定Access-Control-Expose-Headers:
FooBar,则可通过
getResponseHeader('FooBar')获取FooBar字段的值。
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,
浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
三列布局
1,:Float
全局(overflow:hidden)
左边 float:left 右边float:right 中间margin-left:左边的宽度 margin-right:右边的宽度
2:Position
左边 Position:absolute 右边Position:absolute 中间margin-left:左边的宽度 margin-right:右边的宽度 或者margin:0 右宽度 0 左宽度:
3:bfc和float配合使用
<div class="wrap">
<div class="middle">
<div class="main">中间</div> </div>
<div class="left">左侧</div>
<div class="right">右侧</div>
</div>
<style type="text/css">
.wrap {overflow: hidden;}
.left {float: left; width: 200px; height: 100px; background: coral; margin-left: -100%;}
.middle {float: left; width: 100%; height: 100px; background: lightblue;}
.right {float: left; width: 120px; height: 100px; background: gray; margin-left: -120px;}
.main {margin: 0 140px 0 220px; background: lightpink;}
</style>
4:flex布局
仅仅需要将display:flex布局
原型链是什么详解:
https://blog.csdn.net/lxcao/article/details/52743088
js实现继承的方法
1原型链继承
2构造继承
3实例继承
4拷贝继承
5组合继承
6寄生组合继承
http://www.cnblogs.com/humin/p/4556820.html
内存泄漏和垃圾回收机制
http tcp udp websocket
主要关于websocket
Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说
http://www.cnblogs.com/fuqiang88/p/5956363.html
typeof 运算符返回一个用来表示表达式的数据类型的字符串。
可能的字符串有:"number"、"string"、"boolean"、"object"、"function"
和
"undefined"。
堆栈数据结构区别
堆(数据结构):堆可以被看成是一棵树,如:堆排序。
栈(数据结构):一种先进后出的数据结构。
主要的区别由以下几点:
1、管理方式不同;
2、空间大小不同;
3、能否产生碎片不同;
4、生长方向不同;
5、分配方式不同;
6、分配效率不同;
浅拷贝 用object.assign方法
深拷贝
1种:jso.stringify实现
2种:for in实现遍历和复制
3种:利用数组array.prototype.forEach进行copy
https://blog.csdn.net/qq_39083004/article/details/80206336
css单位 尺寸和颜色
http://www.w3school.com.cn/cssref/css_units.asp
网页渲染流程
https://www.cnblogs.com/peteremperor/p/6285449.html
html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树
(1) HTML/SVG/XHTML,解析这三种文件会产生一个 DOM Tree。
(2) CSS,解析 CSS 会产生 CSS 规则树。
(3) JavaScript脚本,主要是通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree.
Css不会阻塞dom解析 但会阻塞dom渲染
https://blog.csdn.net/bg70pvnybv1/article/details/78819711
js判断数据类型的方法
浏览器缓存问题
http://www.cnblogs.com/skynet/archive/2012/11/28/2792503.html
前端模块化cmd amd es6
主线程和异步操作
主线程先执行 执行完再异步操作 。
产生异步操作 set promise.then gnentrate think和white(不确定)
加载速度提升
图片懒加载和预加载 精灵技术 cnd scritp放在css后面执行
节流
函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用。以impress上面的例子讲,就是让缩放内容的操作在你不断改变窗口大小的时候不会执行,只有你停下来一会儿,才会开始执行。
去抖 多次请求 必须等时间间隔运行 多次触发从最后一次深远时间场景:鼠标用户不停点提交
Float与position同时使用
https://blog.csdn.net/qq_27346075/article/details/82288242
rem怎么用?做不同手机的适配怎么做?
rem是css单位;
1rem的大小是通过html下的font-size这个css属性告诉浏览器的;
使用替换px所在的位置即可
箭头函数的特点
https://www.jb51.net/article/50770.htm
vue双向绑定
数据更新视图 视图更新数据
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
Vue源码
https://github.com/answershuto/learnVue
vue依赖收集
https://my.oschina.net/u/2510955/blog/1817177
https://segmentfault.com/q/1010000008455668
说说Cookie和Session的区别?
1、Cookie和Session都是会话技术,Cookie是运行在客户端,Session是运行在服务器端。
2、Cookie有大小限制以及浏览器在存cookie的个数也有限制,Session是没有大小限制和服务器的内存大小有关。
3、Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击。
4、Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。
Session后端如何存储服务器
https://blog.csdn.net/yzi_angel/article/details/52947733
线程与进程
程序一旦运行就是进程,或者更专业化来说:进程是指程序执行时的一个实例。
线程是进程的一个实体。
进程——资源分配的最小单位,线程——程序执行的最小单位。
线程进程的区别体现在几个方面:
第一:因为进程拥有独立的堆栈空间和数据段,所以每当启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这对于多进程来说十分“奢侈”,系统开销比较大,而线程不一样,线程拥有独立的堆栈空间,但是共享数据段,它们彼此之间使用相同的地址空间,共享大部分数据,比进程更节俭,开销比较小,切换速度也比进程快,效率高,但是正由于进程之间独立的特点,使得进程安全性比较高,也因为进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。一个线程死掉就等于整个进程死掉。
第二:体现在通信机制上面,正因为进程之间互不干扰,相互独立,进程的通信机制相对很复杂,譬如管道,信号,消息队列,共享内存,套接字等通信机制,而线程由于共享数据段所以通信机制很方便。。
3.属于同一个进程的所有线程共享该进程的所有资源,包括文件描述符。而不同过的进程相互独立。
4.线程又称为轻量级进程,进程有进程控制块,线程有线程控制块;
5.线程必定也只能属于一个进程,而进程可以拥有多个线程而且至少拥有一个线程;
第四:体现在程序结构上,举一个简明易懂的列子:当我们使用进程的时候,我们不自主的使用if else嵌套来判断pid,使得程序结构繁琐,但是当我们使用线程的时候,基本上可以甩掉它,当然程序内部执行功能单元需要使用的时候还是要使用,所以线程对程序结构的改善有很大帮助。
进程与线程的选择取决以下几点:
1、需要频繁创建销毁的优先使用线程;因为对进程来说创建和销毁一个进程代价是很大的。
2、线程的切换速度快,所以在需要大量计算,切换频繁时用线程,还有耗时的操作使用线程可提高应用程序的响应
3、因为对CPU系统的效率使用上线程更占优,所以可能要发展到多机分布的用进程,多核分布用线程;
4、并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求;
5、需要更稳定安全时,适合选择进程;需要速度时,选择线程更好。
栈存的基本类型 Undefined、Null、Boolean、Number 和 String,这5中基本数据类型可以直接访问,他们是按照值进行分配的,存放在栈(stack)内存中的简单数据段,数据大小确定,内存空间大小可以分配。
堆是引用类型
https://blog.csdn.net/flyingpig2016/article/details/52895620
promise.then类似于Promise.all() ,区别在于 它有任意一个返回成功后,就算完成,但是 进程不会立即停止
一、Pomise.all的使用
常见使用场景 : 多个异步结果合并到一起
Promise.all可以将多个Promise实例包装成一个新的Promise实例。用于将多个Promise实例,包装成一个新的Promise实例。
1.它接受一个数组作为参数。
2.数组可以是Promise对象,也可以是其它值,只有Promise会等待状态改变。
3.当所有的子Promise都完成,该Promise完成,返回值是全部值的数组。
4.如果有任何一个失败,该Promise失败,返回值是第一个失败的子Promise的结果。
https://www.cnblogs.com/richard1015/p/9155564.html
bind call apply 区别
call(对象,对象)apply(对象,数组[])
bind 返回对象 手动调用才执行call apply
call this改变 apply 数组 bind返回一个对象
call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用。
闭包:
Setimeout(函数,时间)
输出i最后的数 如果想输出1234 用闭包 把函数扩起来再跟一个函数 立即执行函数
for循环 用闭包解决 for循环括起来 立即执行 把
(function()),(i))这个函数就会立即执行 而不是等for循环执行完成之后再执行
apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后续参数传参;
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
https三次握手
1. 客户端发起HTTPS请求
2. 服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以是自己制作或者CA证书。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用CA证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。公钥给别人加密使用,私钥给自己解密使用。
3. 传送证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等。
4. 客户端解析证书
这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值,然后用证书对该随机值进行加密。
5. 传送加密信息
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
6. 服务段解密信息
服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一 起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
7. 传输加密后的信息
这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。
8 客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。
PS: 整个握手过程第三方即使监听到了数据,也束手无策。
http://www.cnblogs.com/shangxiaofei/p/5207471.html
HTTPS和HTTP的区别
1. https协议需要到ca申请证书或自制证书。
2. http的信息是明文传输,https则是具有安全性的ssl加密。
3. http是直接与TCP进行数据传输,而https是经过一层SSL(OSI表示层),用的端口也不一样,前者是80(需要国内备案),后者是443。
4. http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
附录
HTTPS一般使用的加密与HASH算法如下:
非对称加密算法:RSA,DSA/DSS
对称加密算法:AES,RC4,3DES
HASH算法:MD5,SHA1,SHA256
Es5和es6继承的区别
https://blog.csdn.net/heyue_99/article/details/54932553
promise封装实现ajax过程
https://blog.csdn.net/qq_35844177/article/details/75217681
ajax常用的三种方式
https://blog.csdn.net/sinat_33388558/article/details/53557888
事件代理和事件委托
https://blog.csdn.net/majian_1987/article/details/8591385
前端加密
Js加密后传输
浏览器插件内进行加密传输
https传输
提升变量
函数提升在变量提升之上
Sessionid
https://blog.csdn.net/qq_33251859/article/details/77481868
css隐藏元素
1、opacity:0
2、visibility:hidden
3、diaplay:none
4、position:absolute
https://blog.csdn.net/heye13/article/details/51720600
浏览器输入网站全过程
https://blog.csdn.net/qq_25622107/article/details/55046413
1)在浏览器中输入网址
2)DNS解析:先在浏览器的缓存中,搜索是否有DNS相应缓存,是否过期
if not
在操作系统的缓存中,搜索是否有DNS相应缓存,是否过期
if not
读取C盘中的host文件,看是否有DNS相应缓存,是否过期
if not
发送域名解析请求
3)TCP三次握手,连接服务器
4)浏览器给服务器发送一个HTTP请求
5)HTTP服务器回应一个永久重定向响应
6)浏览器去访问重定向的服务器
7)服务器处理请求(进行数据库查询,用户判断等)
8)服务器发回响应
9)浏览器开始相应html页面
10)浏览器发送获取嵌入到html中的元素
什么是DOM?
DOM是文档对象模型,是一种用于HTML和XML文档的编程接口。它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式。我们最为关心的是,DOM把网页和脚本以及其他的编程语言联系了起来。文档对象模型把整张网页组织成这样的一个树状的结构,树结构中的每一个元素都被视为一个节点(node)。包括JavaScript在内的各种编程语言都可以通过文档对象模型来访问和改变网页的各种细节。
怎么操作Dom?
一些常用的 HTML DOM 方法:
getElementById(id) - 获取带有指定 id 的节点(元素)
appendChild(node) - 插入新的子节点(元素)
removeChild(node) - 删除子节点(元素)
一些常用的 HTML DOM 属性:
innerHTML - 节点(元素)的文本值
parentNode - 节点(元素)的父节点
childNodes - 节点(元素)的子节点
attributes - 节点(元素)的属性节点
html标签分类?(块级元素和内联元素)
https://blog.csdn.net/qq_41672590/article/details/79185657
js指针问题
异步请求的几种方式
https://blog.csdn.net/qq_39056805/article/details/80568585
1种 用原生js方法
2种基于jquery
(1)$.getJSON(url,[data],[callback])
(2)$.ajx()
(3)$.post(url,[data],[callback])或$.get(url,[callback])
Ajax异步请求的整个过程
https://blog.csdn.net/rogerzhanglijie/article/details/8655315
https://blog.csdn.net/huangzhi455633364/article/details/51287432
第一步得到XMLHttpRequest
第二步打开服务器的连接(请求方式get post 请求url 请求是否为异步)
第三步发送请求 *xmlHttp.send(null)如果不给可能会造成部分浏览器无法发送
第四步 Xmlhttprequest对象的一个事件注册监听器onreadystatechange
(0刚创建 1请求开始 2调用完send()方法3服务器已经开始响应4响应结束)
JS引擎的事件循环机制event loop
https://blog.csdn.net/bangbDIV/article/details/82698768
状态码:
http://blog.liujason.com/1406.html
401 未授权 403禁止 404未找到
304 客户端已经执行了GET请求 但是文件未发生变化
- 怎么处理跨域,JSONP和CORS
https://www.cnblogs.com/banning/p/6250677.html
webstorage和cookie有什么区别
https://www.cnblogs.com/boyuguoblog/p/6203331.html
js继承的方式
原型 构造 实例 拷贝 组合 寄生组合
https://www.cnblogs.com/humin/p/4556820.html
组件封装
js前端组件的封装方法
定义一个类
类中增加一个方法
body中定义一个dom节点
脚本中把dom节点和类定义结合起来 , 实现特定的组件功能
vue组件封装
建立组件的模板,先把架子搭起来,写写样式,考虑你的组件的基本逻辑
然后在引用得组件中 用import引入组件
通过component定义组件名称
在把组件以标签的形式写出来。