前端面试-react

前端面试-记录

1、TS中 interface 和 type 的区别
1、默认导出的方式不同,inerface 支持同时声明,默认导出,而type必须先声明后导出
2、扩展方式不同,interface 用 extends 来扩展,而type 用 & 操作符扩展
2、webpack和gulp的区别
gulp为高级编译程序,在功能上要比webpack应用程序中多
3、loader 和 puligin 的区别
1、Loader直译为"加载器",将其他文件解析为js文件
2、Plugin直译为"插件"。Plugin可以扩展webpack的功能
3、loader运行在打包文件之前(loader为在模块加载时的预处理文件);plugins在整个编译周期都起作用
4、为什么使用jsx的组件中没有看到使用react却需要引入react?
本质上来说JSX是`React.createElement(component, props, ...children)`方法的语法糖。在React 17之前,如果使用了JSX,其实就是在使用React, `babel` 会把组件转换为 `CreateElement` 形式。在React 17之后,就不再需要引入,因为 `babel` 已经可以帮我们自动引入react。
5、js文件上传如何分片上传
1、定义切片大小
2、计算切片总数
3、切割文件

(1)进行分片设置,文件File基于Blob, 继承了Blob的功能,可以把File当成Blob的子类,利于Blob的slice方法进行文件分片处理,并且依次进行上传
(2)分片文件上传完成后,请求合并接口后端进行文件合并处理即可
6、ES6新特性
let(不能重复声明)、const(声明是必须初始化值)、箭头函数、解构、includes、函数默认参数值
7、Umijs 的使用?为什么要用?
为什么使用Umi.js?
1、项目做大的时候,开发调试的启动和热更新时间会变得很长。
2、大应用下,网站打开很慢,有没有办法基于路由做到按需加载。
8、react hooks
1、useEffect:可看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
	1.1:第二个参数:不传,每次都会更新,相当于DidMount、DidUpdate
		           空数组时,初始化执行一次
		           有参数时,参数改变才会执行
	1.2:如何卸载:返回一个函数 useEffect(()=>{return ()=> {'卸载'} },[])
2、useReducer:升级版的useState,用于处理复杂的state对象,比如 下一个 state 依赖于之前的 state 
	链接:https://www.jianshu.com/p/883b42d76cc1
3、useContext:注意点,先使用createContext创建并初始化,然后Provider 指定使用的范围(在其包裹范围内都可使用传入的操作对象),然后在使用到的地方用useContext接受上下文

9、Promise
1、三种状态:pending、resolve、rejected
2、取消promise请求:reject 或者 Promise.race()-(只要有一个请求成功或者失败了就不执行)
3、和async await 的区别:都是非阻塞的,async await是基于Promise实现的,可以说是改良版的Promise,它不能用于普通的回调函数
扩展:Promise、Generator、async/await 的关系
10、 Event Loop(事件循环)
优先执行普通JS代码--> (执行执行栈里面的微任务和宏任务) 微任务(promise.then())-->宏任务(定时器)
11、call、apply、bind区别
1、调用方式区别:call() 、apply() 自动调用,bind是返回对应函数,需要再次调用 bind()()
2、参数区别: call(obj,参数1,参数2) bind(obj,参数1,参数2) 参数是逗号隔开,apply( obj, [ 参数1 , 参数2] ) 参数 是 数组形式

源码实现:

 //call源码实现
        function demo(){
            console.log(this);
            console.log(arguments);
        }
        var obj = {
            neme:"lcy",
            age:2
        }
        Function.prototype.myCall = function(){
            //找出第一个参数,判断第一个参数是否为空,如果为空this还是指向window
            var target = arguments[0] || window//短路运算
            //获取传递的参数
            var _arg  = Array.from(arguments).slice(1)
            target.fn = this;
            target.fn(..._arg);
            //删除fn属性
            delete target.fn;
        }
        demo.myCall(obj,1,2,3)
        // demo.call(obj,1,2,3);
12、闭包
1、什么是闭包:可以访问 一个函数 内部变量 的函数 叫闭包函数,闭包函数简称闭包。
	fun a(){let a = 1; return fun b(){ log(a)}}; 调用:a()() --> 1
2、使用场景:小范围代替全局变量、访问私有变量的特权方法
3、优点: 可以访问一个函数内部变量、闭包变量长期驻扎内存
4、缺点:长期驻扎内存,不会触发垃圾回收机制,可能 内存占用过大 导致 内存泄漏 
扩展:垃圾回收机制:间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
13、this指向:函数的调用方式决定了 this 的指向不同
1、普通函数调用,此时 this 指向 window
2、对象方法调用, 此时 this 指向 该方法所属的对象 
	const obj = { fn: function(){return 'aaa'}} obj.fn() //this指向obj
3、通过事件绑定的方法, 此时 this 指向 绑定事件的对象 如:onclick 
4、定时器的this 指向 window
14、什么是防抖、节流?使用场景?
1、防抖:事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时  例如:search 搜索框
2:节流:在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效  例如:登录按钮
实现防抖节流函数:
1、防抖:
function debounce(fn,wait){
	let timer=null;
	return function(){
		let context=this;
		let args=arguments;
		//如果此时定时器已经存在了,则取消之前的定时器重新计时
		if(!timer){
			clearTimeout(timer);
			timer=null;
		}
		//设置定时器,使事件间隔指定事件后触发
		timer=setTimeout(()=>{
			fn.apply(context,args);
		},wait);
	};
}
2、节流:
function throttle(fn,delay){
	let timer=null;
	return function(){
		let context=this;
		let args=arguments;
		//如果此时定时器已经存在了就直接返回
		if(!timer){
			timer=setTimeout(()=>{
				fn.apply(context,args);
				timer=null;
			},delay);
		}
	}
}
15、虚拟DOM、真实DOM、diff
1、虚拟DOM、真实DOM 的区别:虚拟DOM不会进行排版与重绘操作
2、虚拟DOM的作用:将所有操作累加起来,统计计算出所有的变化后,统一更新一次DOM。
3、diff算法:diff算法是计算出虚拟DOM中与真实DOM中正真发生变化的部分,并且只对该部分进行原生DOM操作,从而减少对整个页面的渲染
16、JS基本数据类型
string、number、null、undefined、boolean、object、symbol、bigint
17、JS中 new 关键字在做什么,原理?
function Student(name,num,age){
             this.name=name;
             this.num=num;
             this.age=age;
         }
var s2=new Student("小明",54321,18)
console.log(s2);  //Student {name: "小明", num: 54321, age: 18}

实现的步骤:
1.new会在内存中创建一个新的空对象
2.new会让this指向这个新的对象
3.执行构造函数里面的代码  目的:给这个新对象加属性和方法
4.new会返回这个新对象(所以构造函数里面不需要return)
18、JS继承方式
1、原型链继承 重点:让新实例的原型等于父类的实例。
	fun Per(){}; Per.prototype = new Person(); let per_1 = new Per();
2、构造函数继承:用.call()和.apply()将父类构造函数引入子类函数
	Parent.call(this)
3、组合继承(组合原型链继承和借用构造函数继承)
	Parent.call(this, name);Child.prototype = new Parent();
4、原型式继承 function createObj(o) {function F(){} F.prototype = o;return new F();}
5、寄生式继承:就是给原型式继承外面套了个壳子
6、寄生组合式继承(常用)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值