前端js八股文大全
一、js的数据类型
值类型(基本类型):数字(Number)、字符串(String)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol,大数值类型(BigInt)
引用数据类型:对象(Object)、数组(Array)、函数(Function)、日期(Date)。
注:Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值(标识符)。
二、什么是函数
JS函数的概念
函数就是把特定功能的代码抽取出来,使之成为程序中的一个独立实体。
- 函数的作用
正如函数的概念, 我们可以根据需要, 将特定的功能用函数来包裹(封装)
- 使用函数的好处
1, 函数可以在同一个程序或其他程序中多次重复使用(通过函数名调用)
2, 使程序变得更简短而清晰 , 提高可读性
3, 有利于程序维护
三、本地对象、内置对象和宿主对象
1.内置对象
js中的内部对象包括Array、Boolean、Date、Function、Global、Math、Number、Object、>RegExp、String以及各种错误类对象,包括Error、EvalError、RangeError、ReferenceError、>SyntaxError和TypeError。
其中Global和Math这两个对象又被称为“内置对象”,这两个对象在脚本程序初始化时被创建,不必实例化这两个对象。
2.宿主对象
宿主对象就是执行JS脚本的环境提供的对象。对于嵌入到网页中的JS来说,其宿主对象就是浏览器
提供的对象,所以又称为浏览器对象,如IE、Firefox等浏览器提供的对象。不同的浏览器提供的
宿主对象可能不同,即使提供的对象相同,其实现方式也大相径庭!这会带来浏览器兼容问题,
增加开发难度。浏览器对象有很多,如Window和Document等等。
3.自定义对象
顾名思义,就是开发人员自己定义的对象。JS允许使用自定义对象,使JS应用及功能得到扩充
四、数组(Array)
1.基本方法
push() 从后面添加元素,返回值为添加完后的数组的长度
pop() 从后面删除元素,只能是一个,返回值是删除的元素
shift() 从前面删除元素,只能删除一个 返回值是删除的元素
unshift() 从前面添加元素, 返回值是添加完后的数组的长度
splice(i,n) 删除从i(索引值)开始之后的那个元素。返回值是删除的元素
concat() 连接两个数组 返回值为连接后的新数组
sort() 将数组进行排序,默认根据ASCII码比较,返回值是排好的数组
reverse() 将数组反转,返回值是反转后的数组
slice(start,end) 切去索引值start到索引值end的数组,不包含end索引的值,返回值是切出来的数组
indexOf() 查找某个元素的索引值,若有重复的,则返回第一个查到的索引值若不存在,则返回 -1
Array.isArray() 检测是否是一个数组
join() 默认是以 "," 隔开,返回的是字符串
2.高阶函数(1)
forEach(callback) 遍历数组,无return 即使有return,也不会返回任何值,并且会影响原来的数组
map(callback) 映射数组(遍历数组),有return 返回一个新数组 。
注意:forEach()和map()的区别
- arr.forEach()是和for循环一样,是代替for。arr.map()是修改数组其中的数据,并返回新的数据。
- arr.forEach() 没有return arr.map() 有return
3.高阶函数(2)
filter(callback) 过滤数组,返回一个满足要求的数组
every(callback) 依据判断条件,数组的元素是否全满足,若满足则返回ture
some() 依据判断条件,数组的元素是否有一个满足,若有一个满足则返回ture
reduce(callback, initialValue) 迭代数组的所有项,累加器,数组中的每个值(从左到右)合并,最终计算为一个值
lastIndexOf() 和arr.indexOf()的功能一样,不同的是从后往前查找
Array.from() 将伪数组变成数组,就是只要有length的就可以转成数组。 —es6
Array.of() 将一组值转换成数组,类似于声明数组 —es6
find(callback) 找到第一个符合条件的数组成员
findIndex(callback) 找到第一个符合条件的数组成员的索引值
fill(target, start, end) 使用给定的值,填充一个数组
includes() 判断数中是否包含给定的值
keys() 遍历数组的键名
values() 遍历数组键值
entries() 遍历数组的键名和键值
五、字符串(String)
字符串的恒定性
字符串的方法修改字符,不会改变原来的字符串,叫做恒定性
字符串的方法
charAt(): 返回指定下标位置的字符。如果index不在0-str.length(不包含str.length)之间,返回空字符串。
charCodeAt(): 返回指定下标位置的字符的unicode编码,这个返回值是 0 - 65535 之间的整数。
indexOf(): 返回某个指定的子字符串在字符串中第一次出现的位置
toLowerCase()把字符串转为小写,返回新的字符串。
toUpperCase(): 把字符串转为大写,返回新的字符串。
lastIndexOf(): 返回某个指定的子字符串在字符串中最后出现的位置。
slice(): 返回字符串中提取的子字符串。
substring(): 提取字符串中介于两个指定下标之间的字符。
split(): 把字符串分割成字符串数组。
substr(): 返回从指定下标开始指定长度的的子字符串
replace(): 在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
match(): 返回所有查找的关键字内容的数组。
concat(): 合并
支持正则的四个方法:
search()
match()
split()
replace()
六、浏览器渲染页面的原理及流程
浏览器将域名通过网络通信从服务器拿到html文件后,如何渲染页面呢?
1.根据html文件构建DOM树和CSSOM树。构建DOM树期间,如果遇到JS,阻塞DOM树及CSSOM树的构建,优先加载JS文件,加载完毕,再继续构建DOM树及CSSOM树。+
2.构建渲染树(Render Tree)。
3.页面的重绘(repaint)与重排(reflow,也有称回流)。页面渲染完成后,若JS操作了DOM节点,根据JS对DOM操作动作的大小,浏览器对页面进行重绘或是回流
七、重绘和回流(repaint&reflow)
当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
1、页面首次渲染
2、浏览器窗口大小发生改变
3、元素尺寸或位置发生改变
4、元素内容变化(文字数量或图片大小改变而引起的计算值宽度和高度改变)
5、元素字体大小变化
6、添加或者删除可见的DOM元素
7、激活CSS伪类(例如::hover)6
8、查询某些属性或调用某些方法
9、offsetWidth,width,clientWidth,scrollTop/scrollHeight的计算,会使浏览器将渐进回流队列Flush,立即执行回流。
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
回流必定会发生重绘,重绘不一定会引发回流。
八、如何避免重绘和回流?
css:
1.避免使用table布局,可能很小的一个小改动会造成整个table的重新布局
2.尽可能在DOM树的最末端改变class。
3.避免设置多层内联样式。
4.将动画效果应用到position属性为absolute或fixed的元素上。
5.动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用requestAnimationFrame
6.避免使用CSS表达式(例如:calc())
7.使用transform替代top
8.使用visibility替换display: none,因为前者只会引起重绘,后者会引发回流(改变了布局)
将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点
js:
1.避免频繁操作样式,最好一次性重写style属性,cssText,或者将样式列表定义为class并一次性更改class属性。
2.避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
3.也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
4.避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
5.对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
九、什么是闭包(Closure)
闭包是这样一种机制:
**函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制所收回. **
闭包的好处:
- 可以让一个变量长期驻扎在内存当中不被释放,在IE6、7、8下会存在内存溢出
- 避免全局变量的污染, 和全局变量不同, 闭包中的变量无法被外部使用
闭包的用途
1.实现缓存
2.存储值与避免变量全局污染
3.函数的柯里化
4.节流和防抖
使用闭包的注意点
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
(2)闭包会在父函数外部,改变父函数内部变量的值。
十、垃圾回收机制(GC)
JS引擎会在一定的时间间隔来自动对内存进行回收(把内存释放)
JS垃圾回收机制有两种: 1, 标记清除, 2, 引用计数
1, 标记清除: js会对变量做一个标记Yes or No的标签以供js引擎来处理, 当变量在某个环境下被使用则标记为yes, 当超出该环境(可以理解为超出作用域)则标记为no, js引擎会在一定时间间隔来进行扫描, 会对所有no标签的变量进行释放(将该变量所占的内存释放掉)
2, 引用计数: 对于js中引用类型的变量, 采用引用计数的内存回收机制, 当一个引用类型的变量赋值给另一个变量时, 引用计数会+1, 而当其中有一个变量不再等于值时, 引用计数会-1, 如果引用计数为0, 则js引擎会将其释放掉
十一、什么是回调函数(callback)
回调函数也是一种高阶函数,把一个函数当做另外一个函数的参数,在另外一个函数内部被执行和传递参数
好处:
1.解决异步
2.对函数进行功能扩展
缺点:
1.容易造成回调地狱,回调地狱不方便维护与理解,
2.解决方案使用 promise + async + await
十二、什么是ajax
AJAX (阿贾克斯 Asynchronous Javascript And Xml ) 异步JavaScript和XML,是指一种创建交互式网页应用的网页开发技术, 可以访问服务器数据的局部刷新的技术
核心对象: XMLHttpRequest
ajax的异步如何获取到数据?
使用
onreadystatechange
事件(事件队列event loop的宏任务),并结合callback
回调函数获取数据
ajax的同步,发送请求时会占据 (thread main)主线程,造成阻塞,不推荐使用
十三、get请求与post请求的区别?
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码(文字,图片,电影…)方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST没有。get做查询post做提交对参数的数据类型,
GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为GET的参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。
GET产生的URL地址可以被Bookmark,而POST不可以。GET请求的速度是POST请求速度的两倍
注意:GET产生一个TCP数据包;POST产生两个TCP数据包。Firefox就只发送一次
get适合做查询post适合做提交
get只接受ASCII字符,而POST没有限制
get请求比post请求快,post比get请求相对安全
post传输的数据量大,可以传输视频音频等
十四、HTTP协议
1.什么是http协议
超文本传输协议Hyper Text Transfer Protocol
它是基于TCP协议的应用层传输协议,
简单来说就是客户端和服务端进行数据传输的一种规则
2.http 协议一共有五大特点:
HTTP 是一个属于应用层的面向对象的协议有五大特点
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种 方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type(Content-Type是HTTP包中用来表示内容类型的标识)加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开式连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
3.请求报文(request)
1.请求行 [请求方式 url地址 协议(1.0/1.1/2.0) ]
2.请求头 [content-type,cookie]
3.请求体 [数据]
4.响应报文 (response)
1.状态行 [协议, 状态码,短语]
2.响应头 [content-Type,...Referer:防盗链]
3.响应体 [数据]
十五、Promise
回调函数是用来解决异步或对函数进行功能扩展,如果滥用回调函数的嵌套,就会形成回调地狱
回调地狱,不方便维护与代码的理解,就可以采用Promise.(不仅能解决回调地狱还能做并发)
promsie是一个类,需要被实例化,微任务
promsie 有三种状态
1.pending 等待 默认是 等待
2.fulfilled 完成
3.rejected 拒绝
它们顺序是不可以逆的
promsie的原型方法
then() 里面有2个函数,第1个函数取resolve的结果,第2个参数取reject的结果
catch() 捕获 reject的结果
finally() 只要执行resolve或reject后,都会执行finally
promise的静态方法
Promise.all() ,all方法里需要填入一个数组,数组里必须都是支持promise的方法,迸发执行
Promise.race(),race方法里需要填入一个数组,谁先完成,就只取谁的结果
Promise.resolve() 只执成功,并返回一个新的promise对象
Promise.reject() 只执失败,并返回一个新的promise对象
ES7 async await
await关键字后面必须接promise对象,有await关键字的地方,必须是一个async 异步函数
它能解决,把异步像同步一样的被调用
十六、同源策略
同源策略是一种浏览器的安全机制,
如果出现 协议,域名,端口,三者不统一,就会产生跨域
https://www.baidu.com
http://www.baidu.com //协议不同,跨域
http://www.baidu.com
http://mail.baidu.com 二级域名
http://aaa.bbb.baidu.com 三级域名 域名不同,跨域
http://www.baidu.com:8080
http://www.baidu.com:5500 端口不一致,跨域
怎么解决跨域(cors)?
目前常见的方案
-
在后端的响应头加上一句
Access-Control-Allow-Origin:*
,这里的*表示所有请求,都可以访问该服务 -
采用非官方的跨域方案 ,JSONP, 它算不上真正ajax请求,它只能算get请求,因为它是利用了带
src
属性的script
,不受限制的访问外部资源,再又结合callback
回调函数获取数据.还要和后端配合使用
-
前端使用webpack模块中的server proxy ,实现服务器端代理,来解决跨域
十七、什么是xss攻击?
**跨站脚本攻击。**XSS的重点不在于跨站点,而在于脚本的执行
恶意攻击者在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候,那么嵌入到web页面中script代码会执行,因此会达到恶意攻击用户的目的
如何防范?
- 后端需要对提交的数据进行过滤(
十八、JSON和JSONP的区别 ?
json 是一种轻量级的数据结构,能跨平台进行网络传输,能做配置文件.
jsonp 是一种非官方的跨域解决方案,它是利用script的src,不受限制的访问外部资源,并结合callback拿到数据
它并不是真正的ajax,它是一个get请求,更加适合做查询.
xml 可扩展性标记语言,是一种重量级的数据格式,也能跨平台进行网络传输和配置文件.
十九、什么是oop(面向对象)
oop是一种编程思想,又叫做面向对象编程(ooa面向对象分析,ood面向对象设计)
它有三大特性
封装 将相同的属性和方法提取成一个类
继承 子类拥有父类的属性和方法
多态
重写 子类重写父类的属性和方法
重载 在同一个类中,同名不同参数 js没有重载
补充: css3大特性
层叠性,继承性,优先级(特殊性)
二十、继承
1. 对象冒充继承 使用 bind,call,apply 解决构造函数属性的继承
缺点:不能继承原型上的属性和方法
2. 原型链继承
缺点:不能让构造函数的属性,初始化
3. 组合继承 (对象冒充+原型继承)
缺点:原型中会有多余的属性,并且是undefined
4. ES6的class和extends继承
5. 寄生组合继承 Object.create(base.prototype);
二十一、递归
1.什么是递归?
函数自己调用自己,要有零界点(结束条件)
2.递归能做什么?
循环的能做的事,递归都能实现
3.递归的使用场景
1. 快速排序使用递归
2. nodejs磁盘文件的遍历,使用递归
3. 管理系统的权限菜单栏(n级菜单栏)
4. 对象的深拷贝
二十二、节流(throttle)与防抖(debounce)
防抖:任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行
触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
// 1、防抖功能函数,接受传参
function debounce(fn,delay==600) {
// 2、创建一个标记用来存放定时器的返回值
let timeout = null;
return function() {
// 3、每次当用户点击/输入的时候,把前一个定时器清除
clearTimeout(timeout);
// 4、然后创建一个新的 setTimeout,
// 这样就能保证点击按钮后的 interval 间隔内
// 如果用户还点击了的话,就不会执行 fn 函数
timeout = setTimeout(() => {
fn.call(this, arguments);
}, delay);
};
}
节流:指定时间间隔内只会执行一次任务。
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
function throttle(fn,delay=600) {
// 1、通过闭包保存一个标记
let canRun = true;
return function() {
// 2、在函数开头判断标志是否为 true,不为 true 则中断函数
if(!canRun) {
return;
}
// 3、将 canRun 设置为 false,防止执行之前再被执行
canRun = false;
// 4、定时器
setTimeout( () => {
fn.call(this, arguments);
// 5、执行完事件(比如调用完接口)之后,重新将这个标志设置为 true
canRun = true;
}, delay);
};
}
节流和防抖的共同点,都是减少执行频率.
函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,
而函数防抖只是在最后一次事件后才触发一次函数
二十三 、defer和async的区别
<script src="./async1.js" async defer></script>
-
defer:在HTML解析完之后才会执行。如果是多个,则按照加载的顺序依次执行。
-
async:在加载完之后立即执行。如果是多个,执行顺序和加载顺序无关
二十四、前端性能优化
-
减少 HTTP 请求数量
- 基本原理:在浏览器与服务器进行通信时,主要是通过 HTTP 进行通信。浏览器与服务器需要经过三次握手,每次握手需要花费大量时间。而且不同浏览器对资源文件并发请求数量有限(不同浏览器允许并发数),一旦 HTTP 请求数量达到一定数量,资源请求就存在等待状态,这是很致命的,因此减少 HTTP 的请求数量可以很大程度上对网站性能进行优化。
- CSS Sprites:国内俗称 CSS 精灵,这是将多张图片合并成一张图片达到减少 HTTP 请求的一种解决方案,可以通过 CSS background 属性来访问图片内容。这种方案同时还可以减少图片总字节数,节省命名词汇量(由命名多张图片文件变成一张,哈哈哈)。
- 合并 CSS 和 JS 文件:现在前端有很多工程化打包工具,如:grunt、gulp、webpack等。为了减少 HTTP 请求数量,可以通过这些工具再发布前将多个 CSS 或者 多个 JS 合并成一个文件。
- 采用 lazyLoad:俗称懒加载,可以控制网页上的内容在一开始无需加载,不需要发请求,等到用户操作真正需要的时候立即加载出内容。这样就控制了网页资源一次性请求数量。
- 基本原理:在浏览器与服务器进行通信时,主要是通过 HTTP 进行通信。浏览器与服务器需要经过三次握手,每次握手需要花费大量时间。而且不同浏览器对资源文件并发请求数量有限(不同浏览器允许并发数),一旦 HTTP 请求数量达到一定数量,资源请求就存在等待状态,这是很致命的,因此减少 HTTP 的请求数量可以很大程度上对网站性能进行优化。
-
控制资源文件加载优先级
- 基本原理:说到这里就需要知道浏览器加载 HTML 内容的原理,浏览器在加载 HTML 内容时,是将 HTML 内容从上至下依次解析,解析到 link 或者 script 标签就会加载 href 或者 src 对应链接内容,为了第一时间展示页面给用户,就需要将 CSS 提前加载,不要受 JS 加载影响。
- 遵循原则:主要文件放在 head 内部,次要文件放在 body 底部。一般情况下都是 CSS 在头部,JS 在底部。
- 基本原理:说到这里就需要知道浏览器加载 HTML 内容的原理,浏览器在加载 HTML 内容时,是将 HTML 内容从上至下依次解析,解析到 link 或者 script 标签就会加载 href 或者 src 对应链接内容,为了第一时间展示页面给用户,就需要将 CSS 提前加载,不要受 JS 加载影响。
-
利用浏览器缓存
- 基本原理:浏览器缓存分强缓存和协商缓存,他们是将网络资源存储在本地,等待下次请求该资源时,如果命中就不需要到服务器重新请求该资源,直接在本地读取该资源。
- 强缓存:在 web 服务器返回的响应中添加 Expires 和 Cache-Control Header。
- 协商缓存:通过【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对 Header 分别管理。
- 基本原理:浏览器缓存分强缓存和协商缓存,他们是将网络资源存储在本地,等待下次请求该资源时,如果命中就不需要到服务器重新请求该资源,直接在本地读取该资源。
-
使用 CDN
- 基本原理:CDN的全称是Content Delivery Network,即内容分发网络。
-
减少重排(Reflow)
- 基本原理:重排是 DOM 的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的 visibility 属性,这也是 Reflow 低效的原因。如果 Reflow 的过于频繁,CPU 使用率就会急剧上升。
- 减少 Reflow,如果需要在 DOM 操作时添加样式,尽量使用 增加 class 属性,而不是通过 style 操作样式。
- 基本原理:重排是 DOM 的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的 visibility 属性,这也是 Reflow 低效的原因。如果 Reflow 的过于频繁,CPU 使用率就会急剧上升。
-
减少 DOM 操作
使用createDocumentFragment
-
图标使用 IconFont 替换
https://www.jianshu.com/p/d9c20eafa67e 网页性能优化
https://segmentfault.com/a/1190000017329980 你真的了解回流和重绘吗
二十五 、值类型和引用类型的区别
【值类型】
1.占用空间固定,保存在栈中,在当前环境执行结束时销毁
2.保存和赋值是值的本身
3.可以使用typeof检测数据类型
4.基本类型数据是值类型
【引用类型】
1.占用空间不固定,保存在堆中,只有在引用的它的变量不在时,会被垃圾回收机制回收。 (引用变量存储在栈中的是指向堆中的数组或者对象的地址 )
2.保存与复制的是指向对象的一个指针
3.使用instanceof检测数据类型
4.使用new()方法构造出的对象是引用型
二十六 、什么是cookie?
基于http协议的一种本地’存储’技术 (它就相当于钱包)
document.cookie="username=qingmu; expires=有效时间 GMT; path=/";domain=;secure;
它的特点:
1.基于http协议,解决无状态问题
2.它会随着请求携带到服务器
3.只能存储’字符串’ 4k左右大小
4.能跨域(设置domain),默认不可以
5.容易被伪造,不安全,会造成 xss攻击 (站点伪造)
它的使用场景:
1.免登录 2.购物车
3.简单的存储,非敏感数据
http协议
常见于 浏览器与服务器的通信,它是属于 应用层 (应用程序)
http 默认的端口 80
http协议的特点
短连接(断开式) 浏览器向服务器发送请求,服务器接受,并响应
无状态 不知道是谁访问了服务器,
- (cookie+session)
- token 凭证
二十七、cookie 、sessionStorage与localStorage的区别
特性 | sessionStorage | localStorage | |
---|---|---|---|
数据的生命期 | 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 | 仅在当前会话下有效,关闭页面或浏览器后被清除 | 除非被清除,否则永久保存 |
存放数据大小 | 4K左右 | 一般为5MB | 一般为5MB |
与服务器端通信 | 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 |
易用性 | 需要程序员自己封装,源生的Cookie接口不友好 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 |
WebStorage(sessionStorage与localStorage)提供了一些方法,数据操作比cookie方便;
1).setItem (key, value) —— 保存数据,以键值对的方式储存信息。
2).getItem (key) —— 获取数据,将键值传入,即可获取到对应的value值。
3).removeItem (key) —— 删除单个数据,根据键值移除对应的信息。
4).clear () —— 删除所有的数据
5).key (index) —— 获取某个索引的key
cookie、localstorage和sessionStorage三者都是临时存储客户端会话信息或数据的方法,下面就简单介绍一下三者的区别:
一、存储的时间有效期不同
1、cookie的有效期是可以设置的,默认的情况下是关闭浏览器后失效
2、sessionStorage的有效期是仅保持在当前页面,关闭当前会话页或者浏览器后就会失效
3、localStorage的有效期是在不进行手动删除的情况下是一直有效的
二、存储的大小不同
1、cookie的存储是4kb左右,存储量较小,一般页面最多存储20条左右信息
2、localStorage和sessionStorage的存储容量是5Mb(官方介绍,可能和浏览器有部分差异性)
三、与服务端的通信
1、cookie会参与到与服务端的通信中,一般会携带在http请求的头部中,例如一些关键密匙验证等。
2、localStorage和sessionStorage是单纯的前端存储,不参与与服务端的通信
二十八、for…in 和 for…of的区别?
推荐在循环对象属性的时候, 使用for…in.
在遍历数组的时候的时候使用for…of。
for…in循环出的是key,for…of循环出的是value
注意,for…of是ES6新引入的特性。修复了ES5引入的for…in的不足
for…of不能循环普通的对象,需要通过和Object.keys()搭配使用
for…of更加强大, 能遍历Array, Map, Set, String,
TypedArray,arguments, 而for in 不能遍历map
二十九、new操作符做了什么?
function Perosn(name, age) {
// 1.在构造函数内部创建一个空对象
// var obj = new Object();
//2. obj.__proto__= Perosn.prototype;
//3.1 Perosn.bind(obj) this指向obj
//3.2 让空对象拥有 属性和方法 (让this有属性和方法)
this.name = name; //属性
this.age = age; //属性
this.run = function () { }//方法
//4. return this; 是隐式 (看不见的,默认)
// return this;
}
var person = new Perosn("旺旺", 6);
console.log(person);
1.在构造函数内部(隐式)创建一个空对象
2.空对象的指针( __ proto __ )指向构造函数的原型(prototype)
3.构造函数的this指向空对象、给空对象添加(自定义的)属性和方法
5.隐式的返回 return this
所以new 能改变构造函数内部的this指向,函数内部的this默认是window
三十 、什么是面向对象?
面向对象是利用对象进行编程的一种思想. 面向对象又被成为 OOP (Object Oriented Programming面向对象编程)
1).为什么要使用面向对象编程?
这种编程方式,更加贴近现实;
2).哪些语言是面向对象?
java,c#, c++ , js … 面向对象编程,是主流;
3).面向对象的特点有哪些?
1)封装
把相同的属性和方法 提取成为一个类
类是抽象的,类是模板
2)继承
子类拥有父类的属性和方法 (偷懒神器)
3)多态
1).重写 (override) (基于继承)
子类重写父类的属性和方法
2).重载 (overload)
同一个类中,同名不同参数 (在同一个类中,函数名称相同,参数的个数和类型不相同)
注意: js没有重载
4).css也有三大特性?
1).继承性
2).层叠性
3).优先级
c/s client -- server 客户端--服务器 功能强大,不方便维护 (需安装)
b/s browser -- server 浏览器--服务器 主流 跨域平台,方便 (无须安装)
5).什么是面向过程?与面向对象有什么区别?
面向过程:
就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,
使用的时候一个一个依次调用就可以了。
面向对象:
是把构成问题的事务分解成各个对象,每个对象都有自己独立的属性和行为,
对象可以将整个问题事务进行分工, 不同的对象做不同的事情,
这种面向对象的编程思想由于更加贴近实际生活, 所以被计算机语言广泛应用。
js有2种编程模式
1.面对过程
2.面向对象
三十一、类和对象的关系
类是对象的抽象,而对象是类的具体实例。
类是抽象的,不占用内存,而对象是具体的,占用存储空间。
类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
类与对象的关系就如模具和铸件的关系
类的实例化结果就是对象,而对一类对象的抽象就是类,
类描述了一组有相同属性和相同方法的对象
三十二、原型
1.什么是原型?
原型, 英文名prototype是函数中一个自带的属性,用来添加公共属性的方法,我们创建的每个函数都有一个
prototype(原型)属性,这个属性是一个对象.
~
2.原型的作用?
原型的作用是: 可以让同一个构造函数创建的所有对象共享属性和方法. 也就是说, 你可以不在
构造函数中定义对象的属性和方法,
而是可以直接将这些信息添加到原型对象中。
3.原型的好处?
优点:
1, 实例对象都有自己的独有属性
2, 同时共享了原型中的方法,最大限度的节省了内存
3, 支持向构造函数传递参数 (初始值)
4.什么是原型链?
当访问一个实列对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找的过程就会形成一个链式结构,我们-称为原型链
三十三 、进程与线程的区别?
-
线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
-
一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
-
进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信
号等),某进程内的线程在其他进程不可见;
- 调度和切换:线程上下文切换比进程上下文切换要快得多
三十四 、AMD、CMD、CommonJs、ES6的对比
CommonJS规范是诞生比较早的,适合服务端,因为在服务器读取模块都是在本地磁盘,加载速度很快.
CommonJS的特点:
-
1.所有代码都运行在模块作用域,不会污染全局作用域。
-
2.模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
-
3模块加载的顺序,按照其在代码中出现的顺序。
AMD的特点
AMD,即 (Asynchronous Module Definition),这种规范是异步的加载模块,requireJs应用了这一规范。先定义所有依赖,然后在加载完成后的回调函数中执行,依赖前置 ,代表作有 require.js库
require(['clock'],function(clock){
clock.start();
});
CMD的特点
CMD (Common Module Definition), 是seajs推出的规范,CMD则是依赖就近,用的时候再require, 就近依赖 代代表有SeaJS 库
define(function(require, exports, module) {
var clock = require('clock');
clock.start();
});
方案 | 优势 | 劣势 | 特点 |
---|---|---|---|
AMD | 速度快 | 会浪费资源 | 预先加载所有的依赖,直到使用的时候才执行 |
CMD | 只有真正需要才加载依赖 | 性能较差 | 直到使用的时候才定义依赖 |
能够提出CMD和AMD互相补充是一个很赞的想法。现在,它们除了希望放在浏览器作为loader也能够放在服务端,提供加载功能。在我看来,AMD擅长在浏览器端、CMD擅长在服务器端。这是因为浏览器加载一个功能不像服务器那么快,有大量的网络消耗。所以一个异步loader是更接地气的。
后期使用webpack之后 AMD和CMD 没有啥意义.加上ES6也出了自己的模块化机制
ES6的模块化
import config from './config' //导入
export default function () { //导出
console.log('fff')
}
注意:
script标签中写js代码,或者使用src引入js文件时,默认不能使用module形式,即不能使用import导入文件,
但是我们可以再script标签上加上type=module属性来改变方式
三十五 、比较运算符的规则
- 数字和数字比较,直接比较大小
- 数字和字符串比较,字符串转换为数字后再比较
- 字符串和字符串比较,进行字符的ASCII码值比较
this的理解
-
单独使用 this,它指向全局(Global)window对象。
-
在对象方法中, this 指向调用它所在方法的对象。
-
函数使用中,this 指向函数的所属者。
-
严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
-
绑定事件this 指向了接收事件的 HTML 元素。
-
apply 和 call 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。
-
箭头函数中this,沿作用域链向外找,直到有this定义(不受内部定时器影响)
堆和栈的区别
get和post的区别
什么是箭头函数
- 没有this,this指向上下文对象
- 不能被实例化
- 没有构造器
- 如果函数体中只有一句代码 且省略了{} 且你需要返回值 那么必须省略return关键词,如果返回的是对象要用括号括起来2