1、Vue双向数据绑定是如何实现的?原文
- vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
- Vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统。
- 访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过 defineProperty() 方法单独定义。
- 访问器属性的"值"比较特殊,读取或设置访问器属性的值,实际上是调用其内部特性:get和set函数。
- get 和 set 方法内部的 this 都指向 obj,这意味着 get 和 set
函数可以操作对象内部的值。另外,访问器属性的会"覆盖"同名的普通属性,因为访问器属性会被优先访问,与其同名的普通属性则会被忽略。
2、极简双向数据绑定是如何实现的?
3、原型和原型链是什么?原文
3、proto 这是每一个JavaScript对象(除了null)都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。
4、construcotr,每个原型都有一个constructor属性指向关联的构造函数
5、实例与原型 当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。
4、总结ES6常用的新特性。 原文
在这里列举几个常用的:
- 箭头函数
- Promise
- Let与Const
- 类
- 模块化
- 函数参数默认值
- 模板字符串
- 解构赋值
- 延展操作符
- 对象属性简写
5、箭头函数。 原文
- 作为匿名函数被调用。
- 作为方法被调用
- 在方法内部被调用
- 使用new 操作符调用,会抛出错误
- 使用call和apply,bind()调用
总结一下
6.promise是什么? 原文
什么是Prmoise
Promise对象的特点:
Promise对象代表一个异步操作,有三种状态:
pending(执行中)
Resolved(成功,又称Fulfilled)
rejected(拒绝)
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected
Promise对象的缺点:
2、如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
3、当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
promise兼容性
Promise的使用
(1)、首先我们new一个Promise,将Promise实例化
(2)、然后在实例化的promise可以传两个参数,一个是成功之后的resolve,一个是失败之后的reject
(3)、Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数
2、链式操作
也许你会说,Promise只是简化层层回调的写法而已吧,其实不然,它的精髓是通过维护状态、传递状态的方式来使回调方式能够及时的调用,因此,相比于callback,它更灵活,更简单。
promise.all方法
all接收一个数组作为参数,p1,p2是并行执行的,等两个都执行完了,才会进入到then,all会把所有的结果放到一个数组中返回,所以我们打印出我们的结果为一个数组。
promise.race方法
7、JS中事件冒泡与捕获。 原文
2、到达target节点,触发事件(对于target节点上,是先捕获还是先冒泡则捕获事件和冒泡事件的注册顺序,先注册先执行)
3、target节点 往 document 方向,冒泡前进,遇到注册的冒泡事件立即触发
总结下就是:
对于target节点则是先执行先注册的事件,无论冒泡还是捕获
8、http和https
(1)http和https的基本概念
https: 是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层。
https协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。
(2)http和https的区别?
https协议是由http和ssl协议构建的可进行加密传输和身份认证的网络协议,比http协议的安全性更高。
2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3.使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443
4.http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
(3)https协议的工作原理
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤。
2.web服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),返回或者说传输给客户端。
3.客户端和web服务器端开始协商SSL链接的安全等级,也就是加密等级。
4.客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
5.web服务器通过自己的私钥解密出会话密钥。
6.web服务器通过会话密钥加密与客户端之间的通信。
9.tcp三次握手,一句话概括
三次握手可以简化为:C发起请求连接S确认,也发起连接C确认我们再看看每次握手的作用:
第一次握手:S只可以确认 自己可以接受C发送的报文段
第二次握手:C可以确认 S收到了自己发送的报文段,并且可以确认 自己可以接受S发送的报文段
第三次握手:S可以确认 C收到了自己发送的报文段
10.TCP和UDP的区别
- TCP是面向连接的,udp是无连接的即发送数据前不需要先建立链接。
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。 并且因为tcp可靠,面向连接,不会丢失数据因此适合大数据量的交换。
- TCP是面向字节流,UDP面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如IP电话和视频会议等)。
- TCP只能是1对1的,UDP支持1对1,1对多。
- TCP的首部较大为20字节,而UDP只有8字节。
- TCP是面向连接的可靠性传输,而UDP是不可靠的。
11.Cookie、sessionStorage、localStorage的区别
Cookie:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下,存储的大小很小只有4K左右。 (key:可以在浏览器和服务器端来回传递,存储容量小,只有大约4K左右)
sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持,localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。(key:本身就是一个回话过程,关闭浏览器后消失,session为一个回话,当页面不同即使是同一页面打开两次,也被视为同一次回话)
localStorage:localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。(key:同源窗口都会共享,并且不会失效,不管窗口或者浏览器关闭与否都会始终生效)
12.自己实现一个bind函数
原理:通过apply或者call方法来实现。
13、preventDefault 和 stopPropagation
例如: 当点击提交按钮时阻止对表单的提交
阻止一下URL的链接
15、为什么要用闭包
闭包的作用在于,可以通过闭包,设计私有变量及方法。
闭包的三大特点为:
2、内部函数可以访问外部函数的变量
3、参数和变量不会被回收。
16、call和apply和bind有什么不一样?
相同点
1、call和apply可以改变this的指向
2、第一个参数都是this要指向的对象
3、都可以利用后续参数继续传参
不同点
2、call和apply都可以传递参数
什么是bind
17、前端性能优化你了解哪些
内容层面
- 使用CDN
- 单域名、多域名,单域名可以减少DNS查找次数,多域名可以增加浏览器并行下载数量,这需要权衡,一般同一个域下不要超过四个资源。
- 避免重定向(分场景)
- 避免404
网络层面
- 利用缓存,可以参考另一篇文章手写文件服务器,说说前后端交互
- 文件压缩(通过响应头Accept-Encoding: gzip, deflate, br告诉服务器你支持的压缩类型)
- 按需加载,提取公共代码,tree-shaking等(都可以通过webpack来实现)
- 减少cookie大小
- 文件合并,通过css雪碧图合并图片
- 文件预加载、图片懒加载
渲染层间
- js放底部,css放顶部
- 减少reflow(回流)和repaint(重绘)
- 减少dom节点
代码层面
- 缓存dom节点,减少节点查找,css选择器层级优化
- 减少dom节点操作
- 合理使用break、continue、return等,优化循环
- 像react用到的事件委托、对象池等手段
18、说说浏览器的reflow和repaint
浏览器解析过程
解析css
把css应用于dom树,生成render树(这里记录这每一个节点和它的样式和所在的位置)
把render树渲染到页面
reflow(回流)
添加或删除元素(opacity:0除外,它不是删除)
改变某个元素的尺寸或位置
浏览器窗口改变(resize事件触发)
repaint(重绘)
元素的颜色、透明度改变
text-align等
19、深拷贝
function deepcopy(obj) {
let res = {};
for (key in obj) {
if (typeof obj[key] == 'object') {
res[key] = deepcopy(obj[key]);
} else {
res[key] = obj[key];
}
}
return res;
}
复制代码
20、defer和async的区别 原文
定义
async:设置此布尔属性,以指示浏览器如果可能的话,应异步执行脚本。
1. 对于defer,我们可以认为是将外链的js放在了页面底部。js的加载不会阻塞页面的渲染和资源的加载。不过defer会按照原本的js的顺序执行,所以如果前后有依赖关系的js可以放心使用。
2. 对于async,这个是html5中新增的属性,它的作用是能够异步的加载和执行脚本,不因为加载脚本而阻塞页面的加载。一旦加载到就会立刻执行在有async的情况下,js一旦下载好了就会执行,所以很有可能不是按照原本的顺序来执行的。如果js前后有依赖性,用async,就很有可能出错。
区别
相同点:
2. 对于inline的script(内联脚本)无效
3. 使用这两个属性的脚本中不能调用document.write方法
4. 有脚本的onload的事件回调
不同点:
2. 浏览器兼容性
3. 执行时刻每一个async属性的脚本都在它下载结束之后立刻执行,同时会在window的load事件之前执行。所以就有可能出现脚本执行顺序被打乱的情况;每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行。
结语
2. 如果async为false,defer为true,那么脚本会在页面解析完毕之后执行。
3. 如果async和defer都为false,那么脚本会在页面解析中,停止页面解析,立刻下载并且执行。
最后给一点个人的建议,无论使用defer还是async属性,都需要首先将页面中的js文件进行整理,哪些文件之间有依赖性,哪些文件可以延迟加载等等,做好js代码的合并和拆分,然后再根据页面需要使用这两个属性。
21、详解toString
22、如何去除字符串首位空格?
//es6
' ab '.trim() //"ab"
//正则
' ab '.replace(/^\s*|\s*$/g,'') //"ab"
复制代码
23、jsonp原理?缺点?
工作原理:使用script标签实现跨域访问,可在url中指定回调函数,获取JSON数据并在指定的回调函数中执行jquery实现jsop。
缺点:只支持GET方式的jsonp实现,是一种脚本注入行为存在一定的安全隐患。如果返回的数据格式有问题或者返回失败了,并不会报错。
24、设计模式
1、工厂模式
function People() {
var obj = new Object();
obj.name = '小明';
obj.age = 12;
obj.say = function() {
// alert(this.name);
return this.name;
}
return obj;
}
2、构造函数模式
function People() {
this.name = '小明';
this.say = function() {
return this.name;
}
}
3、原型模式
function People(name) {
this.name = name;
}
People.prototype.sayName = function() {
console.log(this.name);
}
复制代码
25、继承
1、原型链继承
function People(name) {
this.name = name;
}
People.prototype.sayName = function() {
console.log(this.name);
}
function Student(name, grade) {
this.name = name;
this.grade = grade;
this.sayGrade = function() {
console.log(this.grade);
}
}
Student.prototype = new People();
2、构造函数继承
function People() {
this.name = name;
}
People.prototype.sayName = function() {
console.log(this.name);
}
People.prototype.type = function() {
console.log('人');
};
function Student(name, grade) {
this.name = name;
this.grade = grade;
People.apply(this);
}
var student = new Student('小兰', 5);
student.type();
复制代码
26、HTTP的几种请求方法用途
1、GET方法
发送一个请求来取得服务器上的某一资源
2、POST方法
向URL指定的资源提交数据或附加新的数据
3、PUT方法
跟POST方法很像,也是想服务器提交数据。但是,它们之间有不同。PUT指定了资源在服务器上的位置,而POST没有
4、HEAD方法
只请求页面的首部
5、DELETE方法
删除服务器上的某资源
6、OPTIONS方法
它用于获取当前URL所支持的方法。如果请求成功,会有一个Allow的头包含类似“GET,POST”这样的信息
浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
7、TRACE方法
TRACE方法被用于激发一个远程的,应用层的请求消息回路
8、CONNECT方法
把请求连接转换到透明的TCP/IP通道
27、从浏览器地址栏输入url到显示页面的步骤
- 浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求;链接
- 服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
- 浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM);
- 载入解析到的资源文件,渲染页面,完成。
28、如何进行网站性能优化
1. content方面
-
减少HTTP请求:合并文件、CSS精灵、inline Image
-
减少DNS查询:DNS缓存、将资源分布到恰当数量的主机名
-
减少DOM元素数量
2. Server方面
-
使用CDN
-
配置ETag
-
对组件使用Gzip压缩
3. Cookie方面
- 减小cookie大小
4. css方面
- 将样式表放到页面顶部
- 不使用CSS表达式
- 使用不使用@import
5. Javascript方面
-
将脚本放到页面底部
-
将javascript和css从外部引入
-
压缩javascript和css
-
删除不需要的脚本
-
减少DOM访问
6. 图片方面
- 优化图片:根据实际颜色需要选择色深、压缩
- 优化css精灵
- 不要在HTML中拉伸图片
29、HTTP状态码及其含义
1XX:信息状态码
100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
2XX:成功状态码
200 OK 正常返回信息
201 Created 请求成功并且服务器创建了新的资源
202 Accepted 服务器已接受请求,但尚未处理
3XX:重定向
301 Moved Permanently 请求的网页已永久移动到新位置。
302 Found 临时性重定向。
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。
304 Not Modified 自从上次请求后,请求的网页未修改过。
4XX:客户端错误
400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
401 Unauthorized 请求未授权。
403 Forbidden 禁止访问。
404 Not Found 找不到如何与 URI 相匹配的资源。
5XX: 服务器错误
500 Internal Server Error 最常见的服务器端错误。
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。
31、介绍js有哪些内置对象?
-
Object 是 JavaScript 中所有对象的父对象
-
数据封装类对象:Object、Array、Boolean、Number 和 String
-
其他对象:Function、Arguments、Math、Date、RegExp、Error
32、JavaScript的基本数据类型和引用数据类型?你能画一下他们的内存图吗?
- 栈:原始数据类型(Undefined,Null,Boolean,Number,String)
- 堆:引用数据类型(Object,Array,Function,Data)
- 两种类型的区别是:存储位置不同;
- 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
- 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。不同是,你不可以直接访问堆内存空间中的位置和操作堆内存空间。只能操作对象在栈内存中的引用地址。 链接
总结区别
- 声明变量时不同的内存分配:
- 不同的内存分配机制也带来了不同的访问机制
- 复制变量时的不同
- 参数传递的不同(把实参复制给形参的过程)
33、["1", "2", "3"].map(parseInt) 答案是多少?
-
[1, NaN, NaN]因为 parseInt 需要两个参数 (val, radix),其中radix 表示解析时用的基数。
-
map传了 3个(element, index, array),对应的 radix 不合法导致解析失败。
34、同步和异步的区别?
- 同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作
- 异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容
35、谈一谈let与var的区别?
- let命令不存在变量提升,如果在let前使用,会导致报错
- 如果块区中存在let和const命令,就会形成封闭作用域
- 不允许重复声明,因此,不能在函数内部重新声明参数
36、浏览器兼容问题
- 微信H5
1.设置 overflow scroll 在IOS中滑动不流畅的问题 -webkit-overflow-scrolling: touch
2. 用bootstrap 模态框弹在IOS中弹不出的问题
cursor: pointer;
- 微信小程序
- 上下两张图片之间的空隙,设置img为:display:block;
- 小程序button的边框去不掉的时候,:after{border:none;}
37、判断一个数组
- arr instancof Array
- Array.isArray(arr)
- Object.prototype.toString.call(arr)=='[Object Array]'
38、如何保证一个变量里面的属性不被修改
const object1 = { property1: 42 };
const object2 = Object.freeze(object1);
object2.property1 = 33;
39、splice和slice和substring和substr
分类 | 改变原数据 | 名称 | 第一个参数 | 第二个参数 | 第三个参数 |
---|---|---|---|---|---|
数组方法 | 改变 | splice | start(可负值) | len | add |
数组方法 | 不改变 | slice | start | end | |
字符串方法 | 不改变 | substring | start | end | |
字符串方法 | 不改变 | substr | start(可负值) | len |
40、数组去重
- [...new Set(arr)]
- Array.from(new Set(arr))