前端精简面试题---有这一个就够了(js篇--持续更新)

直接开始

js数据的类型

基本数据类型(值类型):string number boolean undefined null symbol(es6新增)
复杂数据类型(引用类型):array object function math date map set weakmap weakset

值类型与引用类型的区别

1、值类型的key和value都存在栈中
2、引用类型的栈中存的是地址,真正的值在堆里面
3、一个引用类型的堆的值可以被多个变量访问,并且修改其中一个其他都会收到影响

浅拷贝

  1. Object.assign(A,B)
  2. for in遍历拷1贝
  3. {…A}对象扩展

深拷贝

1、转字符串:var obj2 = JSON.parse(JSON.stringify(obj1))
2、递归:

function deeCopy(obj){
    
    
    if(typeof obj==="object"&&obj!==null){
    
    
      var result;
      if(obj.instanceof Array){
    
    
         result = [];
         for(var i=0;i<obj.length;i++){
    
    
               result[i] = deepCopy(obj[i])
         }
      }else{
    
    
         result = {
    
    };
         for(var k in obj){
    
    
             result[k] = deepCopy(obj[k])
         }
      }
      return result;
    }else {
    
    
        return obj;
    }
}

js检测对象类型

typeof:引用类型除function都返回object
instance::是某个函数的实例,在原型链有该函数的返回true
最准确:Object.protoype.toString.call(obj).slice(8,-1)
constructor, Array isArray()

页面渲染过程

1、下载html 生成dom树
2、下载css生成css树
3、css树与dom树合并为渲染树
4、开始渲染页面,遇到js会有阻塞

什么是闭包,闭包的应用场景,闭包的缺点

闭包就是函数嵌套函数,函数作为参数被传入,作为返回值被返回
闭包作用:
1、形成局部作用域
2、 在函数外部可以访问函数内部的局部变量
闭包的缺点
被闭包引用的变量不会被js垃圾回收机制销毁,会常驻内存,使用不当容易造成内存泄露

什么是原型,什么是原型链

每一个构造函数 (class)都有一个显示的原型prototype
每一个实例对象都有一个隐式的原型__proto__
实例的隐式原型__proto__等于其他构造函数的显示原型protype
当查找一个对象的属性或方法时先在实例上查找,找不这沿着__proto__向上逐级查找
我们把__proto__的__proto__形成的链条关系成为原型链
作用:1 原型链实现了js继承,2.原型可以给构造函数创建的实例添加公用方法

JS如何实现继承

1、class使用extends关键字实现继承
2、通用原型链实现继承

function B(){
    
    
     A.call(this) //实现构造函继承
}
B.protoytpe = Object.create(A.prototype) //实现原型继承
B.prototype.= B //修正构造函数

Call,apply的区别

call与apply都是执行一个函数,用第一个参数冒充函数的this
apply参数用的是数组的形式

new关键字做了什么?

1、创建空对象
2、call执行构造并传入空对象作为this
3、指定空对象的构造函数

function A(){
    
    }
var  obj = {
    
    };
a.call(obj);
obj.prototype.constructor = A

事件流

冒泡流:事件由最具体的元素响应,然后组件冒泡到最不具体的元素(html)
捕获流:从最不具体的元素捕获事件
开启捕获 addEventListenter第三个参数 true
阻止事件冒泡:e.stopPropagation()

事件代理

$(父元素).on(事件名,子选择器,响应函数)

把事件注册到多个元素共有的父元素上,通过的冒泡机制 响应事件
作用:动态添加的元素也可以相应事件

数组去重

set 去重
filter过滤

var arr2=arr1.filter((item,index)=>arr1.indexof(item)===index)

异步和同步

同步是按顺序执行,会阻塞代码
异步非阻塞式执行代码
异步方法:回调函数,promise,订阅发布模式,事件响应,aync和awiat

手写ajax

ajax核心是通过XMLHttpRequest(xhr)与服务器异步交换数据,实现 前端刷新试图

var xhr=new XMLHttpRequest();
xhr.open("get","");
xhr.send(data);
xhr.onreadystatechange=function(){
    
    
	if(xhr.reaystate===4){
    
    
		if(xhr===200){
    
    
			//xhr.responseText  获取的数据
		}
	}
}

promise

promise实现异步操作,解决回调函数层级或多形成的回调地狱问题
promise resolve与reject状态发送改变不能更改

var p=new Promise((resolve,reject)=>{
    
    
	var num=Math.random();
	if(num>0.5){
    
    
		setTimeout(()=>resolve(num),2000)
	}else{
    
    
		reject(num)
		}
		})

promise.reject()
promise.all() 多个promise多完成才返回结果
promise.race() 多个promise执行返回最快的一个

你在那些地方用到promise

1、定义api请求端口
2、自定义jsonp用到
3、弹框插件等待用户确定则resolve
4、封装actions 用sync装饰 await实现异步
(等待,网络,等待用户确定的) (异步操作都会用到promose)

get与post区别

1、get 获取数据
2、post 新增 修改 删除
3、put 修改
4、delete 删除
5、get 有缓存 可以收藏书签 方向 数据量2k
6、post 没有缓存 理论上没有大小限制

什么是RESTful

是一个接口的设计风格
每个url地址都是一个资源
使用get获取 post新增 put修改 delete方法删除

如何实现跨域

1、jsonp
2、后端响应头允许
3、代理
无论哪种代理都需要后端支持

箭头函数与普通函数的区别

1、箭头函数的this指向上一层的作用域的this
2、箭头函数不能作为构造函数 ,没有constructor

this指向问题

1、构造函数new 函数()的this指向new出来的对象实例
2、箭头函数的this指向上一层作用域的this
3、对象的this指向对象
4、事件响应函数的this指向调用者
5、setTimout setInterval 的this指向windows
6、call aplly bind 的this指向第一个参数

变量提升

js中 var声明的变量会提升到当前作用域的最前面,赋值为undefined
所有的函数也会被默认提升到作用域的最前面,函数可以先调用后声明

let 与var的区别

1、let不可以变量提升,var可以
2、let不可以重复赋值,var可以
const声明必须赋值,值类型的值不可以修改

获取浏览器宽高

window.innerWidth window.innerHeight
document.documentElement.clientWidth
document.documentElement.clientHeight

clientWidth offsetWidth, scrollWidth区别

clientWidth 内容+padding宽
offsetWidth 内容+padding宽+边框的宽
scrollWith 内容+滚动区域的宽

scrolleft offsetLeft

scrolleft 滚动条滚动距离
offsetLeft 当前元素距离最近定位的父元素的距离

事件event.pageX ,event.pageY,clientX,clienX

事件点击位置

获取元素的边界

element.getBoundingClientRect()

jsonp原理

利用了script标签src没有同源 限制
后端返回的是方法名+()+数据格式+fun(data)
前端提前与定义这个方法就能捕获数据

书写jsonp

function jsonp(){
    
    
    return new Promise(()=>{
    
    
      var  funName = “callback”+Date.now()+Math.random();
      var  script = document.createElement("script");
      src = url+"callback="+funName;
      document.body.appendChild(script);
      script.src = src;
      window[funName]=function(){
    
    
           resolve(data);
           document.body.removeChild(script)
      }
      script. = function(){
    
    reject(err)}
    })

}

冒泡排序

n个数字来排队,两两相比小靠前
最外面循环n-1 内循环n-1-i

var array=[16,25,9,90,23];
			//外层控制轮数
			for (var i =0; i <array.length-1; i++) {
    
    
				//内层控制比较的次数
				for(var j=0;j<array.length-1-i;j++){
    
    
					//两两相比
					if(array[j]>array[j+1]){
    
    
						var temp=array[j];
						array[j]=array[j+1];
						array[j+1]=temp;
					}
				}
			}

猜你喜欢

转载自blog.csdn.net/weixin_48466991/article/details/126942682