前端JS面试题
自己经验总结,都是些常见的面试题,也是博主经常问的,收藏不迷路,会持续新增内容。
POST请求的数据类型
1、Content-Type: application/x-www-form-urlencoded (默认的数据类型)
2、Content-Type: application/json (发送json数据)
3、Content-Type: multipart/form-data (发送文件或图片)
4、Content-Type: text/xml (发送xml数据)
基础数据类型(原始值)
string,number,boolean,null,undefined,symbol,bigint
typeof和instanceof区别
typeof能判断所有的基础数据类型,对象全都显示成object,函数全都显示成function
instanceof 通过原型链去判断,能判断出准确的数据类型
数据类型转换成boolean
除了0,-0,‘’,null,undefined,NaN,false转化成false外,其他的都转化成true
this指向问题
1、对于function(),this指向的是window
2、对于object.function(),this指向的是object
3、对于object=new function(),this指向的是object
注意:对于箭头函数没有this,对于bind,bind在谁身上,this就指向谁
闭包
概念:受限于作用域,函数外部不能访问函数内部的变量,闭包就是函数内嵌套函数,通过return,就能够读取其
他函数内部的变量,可以理解为闭包是连接函数内部和函数外部的桥梁。
举个栗子:
function one(){
var food = "apple";
function two(){
console.log(food)
}
return two
}
var run = one()
console.log(two()) //apple
正常情况下,函数two的作用域仅限于函数one内,应该是访问不到的,但是因为闭包的存在,函数one调用完后将函
数two暴露了出来,并没有被销毁,所以函数two会一直存在。
闭包优缺点:
优点:可以在函数外部访问函数内部的变量;
缺点:因为闭包的变量长期贮存内存中,容易导致内存泄漏和影响性能,解决方法清除不需要的变量。
什么是Event Loop
Event Loop指的是计算机运行的一种机制,因为JavaScript是单线程的,想要执行任务不外乎三种方法:
队列:任务量大容易造成“假死”现象,网页无法响应用户行为;
新建进程:浪费大量时间,也叫“同步模式”或“堵塞模式”;
新建线程:占用多倍系统资源,也闲置了多倍资源;
Event Loop是一个程序结构,用于等待和发送消息和事件。在程序中设置两个线程:一个负责程序本身的运行,称为
"主线程";另一个负责主线程与其他进程的通信,被称为"Event Loop线程"或"消息线程",当遇到等待或空闲时间时
主线程就让Event Loop线程去通知下一个程序接着往后运行,不存在等待时间。等到下一个程序完成操作后,Event
Loop线程再把结果返回主线程。主线程就调用事先设定的回调函数,完成整个任务。由于在空闲时间运行了下一个程
序,所以主线程可以运行更多的任务,提高了效率,这种运行方式也叫“异步模式”或“非堵塞模式”。
JavaScript通过defineProperty模拟v-model实现数据实时更新
Object.defineProperty(obj, prop, descriptor)
obj:绑定的对象;prop:对象obj的key;
例子:<input id="inputVal" type="text" />
<input id="getVal" type="text" />
// js 实现v-model
var obj = {}
Object.defineProperty(obj,"text",{ //给新建的obj新增一个叫"text"的key,并绑定
get:()=>{
return text // 返回text的值
},
set:(value)=>{
document.getElementById("getVal").value = value // 渲染到页面
}
})
document.getElementById("inputVal").addEventListener("keyup",function (e){
obj.text = e.currentTarget.value
})
箭头函数和普通函数的区别
1、箭头函数是匿名函数,不能使用new构造函数
2、箭头函数没有arguments,没有this,使用appl call调用时只需传入一个参数,对this没影响
3、箭头函数没有原型属性,不能当做Generator函数,不能使用yield关键字
注:普通函数的this指向调用者,箭头函数的this永远指向上级的this,且无法改变
apply,call和bind区别
相同点:都是可以改变this的指向
不同点:使用方法不同,传递参数不同,都是传两个参数,apply传数组,call和bind传字符串,apply和call立即
执行,bind返回的是函数,还需要再执行一次
递归实现深拷贝
const deepCopy = (obj) => {
if( typeof obj !== 'object' || obj === null) return //是否为对象且不为空
let target = Array.isArray(obj) ? [] : {} //兼容数组
for( let k in obj){
if( obj.hasOwnProperty(k)){ //检测属性是否为对象的自有属性
if(typeof obj[k] === 'object'){
target[k] = deepCopy(obj[k])
}else{
target[k] = obj[k]
}
}
}
return target
}