整理JavaScript的面试题
- 1.js数据类型
- 2.数据类型判断方法?
- 3.延迟加载JS有哪些方式?
- 4.null和undefined的区别?
- 5. == 和 ===的区别?
- 6.js的事件循环机制
- 7.js的作用域
- 8.new 操作符做了什么?
- 9. 原型和原型链
- 10. 闭包
- 11.防抖和节流
- 12.call、apply、bind的区别
- 13.浅拷贝和深拷贝
- 14.localStorage、sessionStorage、Cookie的区别
- 15. JS循环常用方法的区别
- 16.this了解以及场景
- 17.跨域解决方案
- 18.从输入url地址到看到页面,中间都经历了啥?
- 19.HTTP和HTTPS的区别?
- 20.基于JS实现Ajax并发请求的控制
- 21.浏览器的缓存机制
- 22.js中的事件委托?
- 23.js事件传播机制
- 24.TCP(传输控制协议)和UDP(用户数据报协议)的区别?
- 25.模块化开发的理解
- 26.Ajax和axios的区别?
1.js数据类型
分为两种:
- 基本数据类型:String、Number、Boolean、null、undefined、Symbol
存储在:栈内存中 - 引用数据类型:Object、Array、Function、正则、Date
地址存在栈内存中,真实数据存在堆内存中
2.数据类型判断方法?
-
typeof 变量名
判断基本数据类型,返回基本类型的小写字符串类型
判断 null 、普通对象、数组 为 ‘object’为什么判断 null 为 ‘object’?
因为是基于二进制进行检测,对象存储在计算机中是以000开始的二进制存储,null:000 -
A instanceof B
返回true/false;可以判断对象是否是某个类的实例,但是不能判断基本数据类型,但他的包装类却是可以的:let s = new String('h')
s instanceof String
只要当前类出现在实例原型链上,结果都为true
arr instanceof Array // true
arr instanceof Object //true
-
constructor
判断对象的构造函数,但是不能判断undefined和null,会报错
(1).constructor===Number //true
[].constructor===Array //true
'aa'.constructor===String //true
-
Object.prototype.toString.call() 可以判断所有数据类型
例如:Object.prototype.toString.call('k').call // '[object String]'
Object.prototype.toString
//返回当前实例所属类的信息
Object.prototype.toString.call('k').slice(8,-1).toLowerCase() //string
数据类型隐式转换
true+1=2
‘name’+true=‘nametrue’ //字符串和其他类型相加=他们连接
undefined+1=NAN
判断是否是 NAN
let isN=undefined*1 // NAN
isNAN(isN) // true
3.延迟加载JS有哪些方式?
async:和HTML解析同步,如果有多个谁先加载完谁先解析
defer:等HTML全部解析完成,才会执行JS代码,如果有多个会依次执行js脚本
<script defer/async src="a.js"></script>
4.null和undefined的区别?
- 数据类型不一样
用typeof判断,null的数据类型是object,undefined的数据类型是undefined - 转化为数字不一样
Number(null) // 0
Number(undefined) // NAN
- null代表空
如果定义的变量准备用于保持对象,可以将变量初始化为null - undefined 变量被声明,但是没有赋值
调用函数时,应该提供的参数没有提供,该参数等于undefined
null==undefined //true
null===undefined //false
5. == 和 ===的区别?
==:比较的是值相等
'1'==1 // true
或者 1==true // true
===:除了比较值相等,还比较数据类型是否相等
'1'==1 // false
或者 1==true // false
6.js的事件循环机制
js代码的执行流程:
- 先是执行所有同步任务,碰到异步任务放到任务队列中
- 同步任务执行完毕,再执行任务队列,任务队列包括宏任务和微任务
- 先执行任务队列中的所有微任务
- 然后执行一个宏任务
- 然后再执行所有的微任务
- 再执行一个宏任务
- 再执行所有的微任务·······依次类推到执行结束
注意:要执行宏任务的前提是清空了所有的微任务
微任务包括:promise.then/catch/finally;nextTick;若同时存在promise和 nextTick,则先执行nextTick
宏任务包括:主代码块,setTimeout、setInterval、I/O、UI 交互事件
7.js的作用域
作用域就是限制某个变量只能在某个区域内有效
分为:全局作用域、局部作用域、块级作用域
全局作用域:在代码中任何地方都能访问到
局部作用域:在固定的代码片段内可以访问到
块级作用域:通过let和const声明,由一对花括号包裹,在指定块的作用域外无法访问到
作用域链:内部可以访问到外部的变量,但是外部不能访问到内部的变量
注意:如果内部有,优先查找内部,内部没有就查找外部
优先级:声明变量>声明普通函数>参数>变量提升
8.new 操作符做了什么?
- 创建一个空对象
let newobj = new Fn() - 将空对象的原型,指向构造函数
newobj__proto__=Fn.prototype - 将构造函数的this指向新对象
原来函数内的this指向window,用new后this指向函数对象 - 根据构建函数返回类型做判断
如果是值类型,返回newObj。如果是引用类型,就返回这个引用类型的对象
functoin newFunc(func,...args){
let newObj={
}
newobj__proto__=func.prototype
const res=func.apply(newObj,args)
return res instanceof Object?res:newObj
}
9. 原型和原型链
原型:
Fn函数有显示原型 prototype,指向函数的原型对象
new实例化一个f函数,有隐式原型 proto,指向创建该对象的函数的原型
原型链:
f.proto 指向Fn.prototype;而 Fn.__proto__指向创建他的原型对象,直到顶层对象Object的原型对象
原型链的最顶层是null
对象查找属性或方法的顺序:
先在对象本身找 —> 构造函数中找 —>对象原型 ---->构造函数原型 —>当前原型的原型中Object找
10. 闭包
闭包:能够读取其他函数内部变量的函数
形成的条件:嵌套的子函数,引用了嵌套的外部函数的属性或者方法时,产生闭包。
示例:
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
}
}
const counter = createCounter();
counter(); // 输出1
counter(); // 输出2
counter(); // 输出3
特性:函数嵌套、内部函数可以直接访问外部函数的内部变量或参数、变量和参数不会被垃圾回收机制回收
优点:变量长期驻扎在内存中、避免全局变量的污染、私有成员存在
缺点:变量驻留在内存中,造成内存损耗问题
解决:把闭包的函数设置为null
应用场景:防抖的封装
11.防抖和节流
- 防抖 debounce
连续快速的触发,只会执行一次
场景:input标签输入完毕发请求 等(实时查询)
function debounce(fn,wait){
let timer=null;
return (...arg)=>{
if(timer) clearTimeout(timer);
timer=