1、JS的数据类型
- 1、JS的数据类型可以分为基本数据类型和引用类型
- 基本数据类型有:String(字符串)、Number(数值)、Boolean(布尔值)、null()、undefined(未定义)、ES6中新添加了Symbol(唯一值)、binInt(大的整数值)
- 引用类型有:Object(对象)、Function(函数)、Date(日期)、RegExp(正则)、Array(数组)
- 基本数据类型与引用数据类型的区别:
- 1、基本数据类型存放到栈中,引用数据类型存放到堆中
- 2、基本数据类型比较的是值,引用数据类型比较的是是否指向同一个地址
2、null与undefined的区别
- null表示为值为空的对象,指向的是一个空对象,转为数值为0
- undefined表示为未定义的值,当变量声明了但没有定义的时候,应为undefined
- 相同点:它们都是值为空的,==的时候为true
- 不同点:类型不一样,null的数据类型为Object,undefined的数据类型为undefined,===为false
3、检测数据类型的方法
- 1、typeof:检测数据类型,基本数据类型可以检测出来,但引用类型不能细分,都为Obejct
- 2、instanceof:比较数据类型
- 3、constructor:获取当前构造器
- 4、Object.prototype.toString().call:获取当前实例所有的类信息(最为准确)
4、==
与===
的区别
- 1、
==
是等于,它会比较值,如果类型不一样,它会强制转换后再比较值 - 2、
===
是全等于,类型和值都会比较,不会强制转换,其中有一个不同,均为false
5、作用域和作用域链
- 一个变量的使用范围就叫做作用域,作用域可以分为全局作用域和局部作用域。
- 一个HTML就是一个全局作用域,一个函数就是一个局部作用域。
- 当查找对象的某个属性时,先会查找它当前的内部作用域,如果没有找到就往上一层作用域找,一直找到全局作用域,这个链式查找的过程就叫做作用域链。
6、判断数组类型的方法
- 1、Array.isArray();
- 2、arr.constructor.toString().indexOf(‘Array’)
- 3、Object.prototype.toString().call(arr)
7、宏任务与微任务
- JS的异步任务可以分为宏任务与微任务
- 宏任务有setInterval、setTimeOut计时器、Ajax
- 微任务就是promise.then、promise.catch、promise.finally
- 宏任务与微任务的执行操作顺序为:
- 1、当一个宏任务进行时,它会观察是否有微任务
- 2、如果有微任务,当这个宏任务完成之后,就会立即处理当前所有的微任务
- 3、当所有的微任务完成后,才进行下一个的宏任务
- 4、所以微任务优先,宏任务与微任务交替执行。
8、new对象的操作过程
- 1、创建一个新的对象
- 2、构造函数指向这个对象
- 3、执行这个构造函数的所有代码
- 4、返回这个新的对象
9、闭包
- 函数里面嵌套一个函数,里面的函数就叫做闭包。
- 优点:闭包可以调用外层函数的变量,实现数据共享,变量始终保持在内存之中,延长变量的生命周期。
- 缺点:闭包执行完之后,外层函数的变量不会被销毁,而是存放在内存中,容易信息泄露,所以如果没有用的信息的话,就删除掉,减少内存损耗。
- 闭包的应用场景:防抖、节流
10、原型与原型链
- 原型就是一个对象,原型对象可以分为显性原型对象和隐性原型对象。
- 显性原型对象就是prototype,它是函数对象所特有的,指向Object。
- 隐性原型对象就是__proto__,它是所有对象都拥有的,对象的隐性原型对象指向它的构造函数的显性原型对象。
- 原型链就是:当查找对象的属性或者方法的时候,就会在对象内部找,如果没有,就通过隐性原型对象这条链,指向构造函数的显性原型对象,就在构造函数里面找,如果没有找到就通过显性原型对象这条链,指向Object,直到找到为止,这个链式查找的过程,就叫做原型链。
11、为什么0.1+0.2!=0.3,如何相等?
- 因为精度缺失,浮点数相加要转为二进制,然而存储空间并没有这么大,所以需要进1去0,导入二进制相加精度缺失,所以0.1+0.2!=0.3
- 解决方案:可以变成整数后相加,再返回浮点数。
12、回调函数
- 一个函数被作为参数被另一个函数所调用,这个函数就叫做回调函数。
- 简单来说,就是你定义了一个函数,但是你没有立即使用它,而是用另一个函数调用它,这就叫做回调函数。
- 优点:业务逻辑分离,耦合性降低。
- 缺点:回调函数以前被用来执行异步操作,这样的话,异步操作增多,就会不断嵌套,造成回调地狱,观赏和维持起来很难,所以ES6新添加了一个Promise对象来解决这个回调地狱问题。
13、Promise对象
- Promise对象是ES6新添加的一个用来处理异步操作的对象。
- Promise有3个状态:pending(进行中)、fulfilled(已完成)、rejected(已失败)
- Promise有2个特点:
- 1、它的状态不受外界的影响
- 2、它的状态变化只能有2种1,一种是从pending转为resolved,一种是从pending转为rejected。
- Promise的好处:
- 1、比传统的回调函数更加规范化
- 2、支持链式调用,有效解决了回调地狱问题
14、递归
- 函数内部调用自己,就叫做递归。
- 递归有两个条件,一个是自己调用自己,一个是要有结束条件,返回之前的所有结果。
- 最常见的应用场景就是阶乘,如求5的阶乘就返回5相乘,再返回调用自己(n-1),直结束条件为1,返回之前相乘的数,实现5的阶乘。
15、变量提升和函数提升
- 在JS编译过程中,会把变量的声明语句提到作用域的最顶部,实现变量提升。函数提升也是一样的。
- 这样的好处就是:
- 1、一次性编译完成,下次调用的时候就不用再编译,优化性能。
- 2、防止出错,可以先调用再声明也不会报错。(不推荐,还是严格遵守,先声明后定义,所以ES6新添加了let)
16、ES6的新特性
- 1、添加了let定义变量,没有变量提升,不允许重复声明,具有块级作用域,让变量声明更规范化。
- 2、添加了const定义常量。声明定义之后就不能修改,适合于不变的量。
- 3、添加了模板字符串(反引号),可以换行也可以嵌套变量
${}
,不用再拼接字符串。 - 4、添加了Pomise对象,来用解决异步操作问题。
- 5、结构赋值(数组、对象、字符串)
- 6、数组的扩展(set和map)
- 7、函数的扩展,可以使用箭头函数
=>
。
17、DOM
- DOM是Document-Object-Model的简写,叫做文档对象模型,它通过大量的API接口来给我们提供获取、添加、修改、删除元素的方法。
- 比如说:
- 1、获取元素节点:document.querySelctor(‘’)
- 2、添加元素节点:document.createElement(‘h1’)
- 3、修改元素节点:element.appendChild()
- 4、删除元素节点:element,removeChild()
18、BOM
- BOM是Browser-Object-Model,就是浏览器对象模型,BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。
- 如window对象方法,如alert(),prompt()等。
- 例如计时器和location对象,location.href获取或者设置整个URL。
19、cookie和session的区别
- 共同点:都是用来跟踪浏览器用户身份的会话方式
- 不同点:
- 1、cookie放在浏览器中,session放在服务器
- 2、cookie不安全,容易被修改,session比较安全
- 3、cookie容器大小只有4K,session比较在
- 使用场景:cookie不安全,session被调用多了会比较消耗性能,所以cookie适合存放不太重要的信息且经常被调用的,session比较适合放密码等重要信息。
20、cookie,sessionStorage和localStrorage的区别
- 共同点:都是放在浏览器中的
- 不同点:
- 1、cookie的大小只有4K,sessionStorage和localStrorage的大小有5M
- 2、cookie的在有效期内可以使用,关闭浏览器后就没有了。sessionStorage仅保存到浏览器中,关闭就没有了。而localStorage在有效期内可以使用,关闭浏览器后也保存下来,除非你用去删除。
- 3、cookie需要访问服务器,sessionStorage和localStrorage不需要访问服务器。
21、数组去重的方法
- 1、indexOf():返回某个元素第一次出现的位置,如果为-1,那就之前没有出现过,添加到新的数组中,不是就不添加。
- 2、对象属性:添加一个新的对象,用来记录元素出现的次数,没有出现过,就添加到新的数组中,有就不添加。
- 3、ES6新添加的set方法:set是唯一值,不重复的,可以写[…new Set()]或者也可以这样写Array.from(new Set())
22、实现继承的方法
- 1、通过原型链继承
- 2、通过构造函数继承
- 3、组合继承(原型链+构造函数)
- 4、ES6新添加的类继承
23、防抖(debounce)与节流(throttle)
- 防抖就是防止数据抖动,将多次触发转为一次触发,去掉多余的操作,优化性能。可以用setTimeOut计时器来实现,判断之前是否有触发操作,如果用就clearTimeOut来清除之前的触发操作,然后再新建一个setTimeOut计时器来触发。
- 节流就是在一定时间内只能触发一次,就叫做节流。也是用setTimeOut计时器来实现。当输入数据时,触发事件为真,然后进行触发操作,操作完之后,把触发事件改为假,等待下一次触发。
- 防抖的应用场景:表单按钮的提交,例如登录发送请求,避免用户点击太快,发送多次请求。文本编辑器实时保存,当无任何更改操作一秒后进行保存。
- 节流的应用场景:鼠标不断点击触发,抢优惠卷,规定n秒内多次点击只有一次生效。
24、浅拷贝与深拷贝
- 浅拷贝复制的是对象地址,新的对象修改值后,原对象也会跟着修改,因为它们指是都是同一个对象地址。
- 深拷贝复制的是对象的值,新建一个对象地址,新的对象修改后,原对象不会受到影响。
- 浅拷贝的方法:
- 1、newObejct=oldObejct
- 2、Obejct.assign(newObject,oldObject)
- 3、newObject=[…new Set(oldObject)]
- 深拷贝的方法:
- 1、递归:判断是否为对象,是的话先遍历对象里面的值复制,不是就直接复制。
- 2、JSON.toString()转为JOSN字符串,再用JSON.parse()转为JSON对象
25、事件循环机制(EventLoop)
- 事件循环有2种任务,一种是宏任务,一种是微任务。
- 关键步骤如下:
- 1、执行一个宏任务
- 2、执行过程串如果遇到微任务,就将它添加到微任务的队列中
- 3、宏任务执行完成之后,立即执行当前所有的微任务
- 4、当宏任务执行完毕之后,开始检查渲染,渲染完毕之后,JS线程继续接管
26、事件捕获和事件冒泡
- 事件捕获就是事件响应从Window开始,逐层向内层前进,到Document文档,到HTML,到目标元素节点,这个过程就是事件捕获。
- 事件冒泡正好相反,执行完成之后,就从目标元素开始,一直到Window,这个过程就叫做事件冒泡。
27、箭头函数和普通函数的区别
- 箭头函数没有this,它的this是继承它的父类的this,所以它的this指向是固定的
- 箭头函数不能作为构造器,因为它没有this,因此它也没有prototype属性
- call、apply、bind不能改变箭头函数的this的值
28、call、apply、bind的区别
- 相同点:都是改变上下主的this指向,第一个参数相同
- 不同点:
- 1、传参不同,call和bind是逐个传参,apply是数组传参
- 2、返回机制不同,cal和apply是立执行,而bind是返回一个函数,调用它才能执行。
29、promise与async/await的区别
- 相同点:都是用来处理异步请求的
- 不同点:
- 1、async/await更加优雅简洁,代码看起像同步代码一样。不用像promise,还需要调用then来获取返回结果。
- 2、promise 更多应用在函数封装中,async用在函数的使用中
30、同步和异步的区别
- 同步:发送一条请求,等到这条请求完成后,下一条请求才能执行。
- 异步:发送一条请求,不需要等待,直接下一条,不影响下一条请求的执行。
- 不同点:同步需要等待,异步不需要。
- 同步优缺点:同步执行效率低,但可以掌握执行流程,避免意外发生。
- 异步优缺点:异步执行效率高,节省时间,但消耗性能且不易掌握执行流程。
31、判断this的方向
- 1、普通函数:谁调用的函数,this就指向谁,如果没有调用,就指向window
- 2、箭头函数:箭头函数没有this,是继承它的父级this指向
- 3、对象调用:当函数被作为对象所调用时,this指向这个对象
- 4、call/apply/bind:改变this的指向,但不能改变箭头函数
32、Set和Map的区别
- 1、Set是值的集合,Map是键值对,键和值都可以是任何值。
- 2、Set的值是唯一的可以做数组去重,Map没有格式限制,可以做数据存储。
33、var、let、const的区别
- 1、var可以变量提升,let和const不可以
- 2、var可以重复声明,let和const不可以
- 3、var没有块级作用域,let和const有
- 4、var和let可以修改变量,const不可以
34、Ajax的原理
- Ajax,它是浏览器提供的一种方法,实现页面无刷新就可以更新数据,提高用户浏览器应用的体验。
- 应用场景:1、页面上拉加载更多的数据。2、列表数据无刷新分页。3、表单项离开焦点数据验证。4、搜索框提示文字下拉列表。
- Ajax原理:Ajax相当于浏览器发送请求与接收响应的代理人,以实现在不影响浏览器页面的情况下,局部更新页面数据,从而提高用户体验。
- Ajax的实现步骤:
- 1、创建Ajax对象:
var xhr=new XMLHttpRequest();
- 2、告诉Ajax请求地址以及请求方式:
xhr.open('get','http://www.baidu.com');
- 3、发送请求:
xhr.send();
- 4、获取服务器端给客户端的响应数据:
xhr.onload=function(){console.log(xhr.responseText);}