React面试题(三)

本文介绍了React组件间的通信方式,如父子组件、兄弟组件和Context,以及TypeScript中的闭包、状态管理(如Redux)、数组合并、访问修饰符、枚举、方法重写、深浅拷贝和Umi中的路由权限与跳转参数。
摘要由CSDN通过智能技术生成

1.React如何进行组件通信?

父传子:父组件中定义一个自定义属性,自定义属性的值就是要传递的数据
子传父:在父组件中定义一个回调函数,通过父传子的方式将这个函数传递给子组件,子组件进行调用,函数的参数就是要传递的数据
兄弟组件之间的通信包括状态提升和发布订阅模式
状态提升就是子传父然后父传子
发布订阅模式就是订阅者提供一个回调函数,保存在数组中,发布者去调用这个回调函数
Context跨组件通信,创建一个contenxt对象,从中导出provider和consumer组件,provider组件包裹跟组件,value就是要传递的数据,子组件如果是类组件那么就创建一个静态方法contextType,然后通过this.Context获取到要传递的数据,如果是函数组件,那么就需要用consumer包裹组件,返回一个jsx,函数的第一个参数就是要传递的数据
还有状态管理工具redux,react-redux,@reduxjs/toolkit

2.闭包的理解以及应用场景

闭包通俗来讲就是一个函数嵌套一个函数,内部函数可以访问外部函数的变量,形成一个封闭的作用域。
闭包的优点:
1.数据封装:闭包可以将变量封装在函数内部,避免全局变量的污染,提高代码的可维护性和可复用性。
2.保持状态:闭包可以保持函数的状态,及时函数已经执行完毕,闭包中的变量仍然可以被访问和使用。
3.实现私有变量和方法:通过闭包,可以创建私有变量和方法,只能在函数内部访问,外部无法直接访问和修改。
闭包的缺点:
1.内存消耗:闭包会引用外部函数的变量,导致这些变量无法被垃圾回收,可能会占用更多的内存。
2.性能问题:由于闭包会涉及作用域链的查找,会增加函数的执行时间和内存消耗。
3.潜在的内存泄漏,如果闭包中引用了外部函数的变量,导致这些变量不再使用,但是闭包仍然存在,可能会导致内存泄漏。
应用场景:
1.封装私有变量和方法
2.延长变量的生命周期
3.原生js实现防抖节流

3.JS数组之间进行合并,写出三种合并方式

1.使用数组的concat方法

	let arr1=[1,2,3]
    let arr2=[4,5,6]
    let merge=arr1.concat(arr2)
    console.log(merge)

2.使用扩展运算符…

	let arr1=[1,2,3]
    let arr2=[4,5,6]
    // let merge=arr1.concat(arr2)
    let merge=[...arr1,...arr2]
    console.log(merge)

3.使用第三方库lodash的 concat() 合并
4.使用for循环

	let arr1=[1,2,3]
    let arr2=[4,5,6]
    // let merge=arr1.concat(arr2)
    // let merge=[...arr1,...arr2]
    for (let i in arr2){
        arr1.push(arr2[i])
    }
    console.log(arr1)

4.TypeScript支持的访问修饰符有哪些?

1.public:所有定义成public的属性和方法都可以在任何地方进行访问。public是默认的修饰符
2.static:静态方法,只能在类内部访问
3.private:所有定义成private的属性和方法都只能在类定义内部进行访问。
4.protected:受保护的修饰符,只能在类内部以及继承的子类中访问,不能再实例化对象中访问
5.readonly关键字将属性设置为只读的,不能修改。

5.如何将 unknown 类型指定为一个更具体的类型?

进行类型断言,类型断言就是说告诉编译器,他就是这个类型,你不用去检查了。
类型断言的方法有两种
1.值 as 类型
2.<类型>值

1  const value: unknown = "Hello World";
2  const foo: string = value; // Error
3  const bar: string = value as string; // OK

只有对已经类型断言的数据才能实现给别的变量赋值。

6.解释一下TypeScript中的枚举?

枚举( mei ju ) : 枚举的意思就是一一列举, 把所有情况都列举出来, 那么取值的时候, 只有这几个可以使用, 其他的都不行。
TypeScript枚举使用关键字“enum”来定义一个新的枚举类型。例如:

enum Direction {
  Up,
  Down,
  Left,
  Right
}

自定义枚举值
您可以通过自定义枚举值来覆盖默认的自动递增行为。例如:

enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}

要访问枚举值,只需使用点表示法即可。例如:

console.log(Direction.Up); // 输出1
console.log(Direction.Down); // 输出2

7.TypeScript中的方法重写是什么?

为了提高效率效率,我们通常会用到重载和重写两种那个方式。
一、重载
重载:方法名称相同,参数的类型或者个数不同。
重载是面向对象编程的一种特有的方法,它允许一个函数在实现的过程中有多个入口,而且只需要实现一次
二、重写
重写:方法名称,参数名称,返回值类型全部相同
特点:当父类和其派生类拥有同一个方法时,这种情况就是方法的重写

8.Js中深拷贝和浅拷贝的定义以及具体实现都有哪些方法?

理解概念

如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
1.如果是基本数据类型,名字和值都会储存在栈内存中。
当然,这也算不上深拷贝,因为深拷贝本身只针对较为复杂的object类型数据
2.如果是引用数据类型,名字存在栈内存中,值存在堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值。

实现的方法

(1)采用递归去拷贝所有层级属性

function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,3,4],
    b=deepClone(a);
a[0]=2;
console.log(a,b);

(2) 通过JSON对象来实现深拷贝
缺点: 无法实现对对象中方法的深拷贝,会显示为undefined

function deepClone2(obj) {
  var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}

(3)lodash函数库实现深拷贝

let result = _.cloneDeep(test)

9.Umi中如何实现路由权限,实现按钮权限?

export default {
  routes: [
    { path: '/user', component: 'user',
      wrappers: [
        '@/wrappers/auth',
      ],
    },
    { path: '/login', component: 'login' },
  ]
}
import { Redirect } from 'umi'

export default (props) => {
  const { isLogin } = useAuth();
  if (isLogin) {
    return <div>{ props.children }</div>;
  } else {
    return <Redirect to="/login" />;
  }
}

10.Umi路由跳转传参方式都有哪些?

import { history } from 'umi';

// 跳转到指定路由
history.push('/list');

// 带参数跳转到指定路由
history.push('/list?a=b');
history.push({
  pathname: '/list',
  query: {
    a: 'b',
  },
});

// 跳转到上一个路由
history.goBack();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值