2021 面试笔记(react +js)

··写在前面:记录一下最近自己面试的面试题以及答案,用作自己看,如有不对,后续指正更改。(两年经验,主要技术栈react ,小白程序媛👧🏻)··

Q1.介绍一下js的数据类型

  • 7 种原始数据类型: Null Undefined String Number Boolean BigInt Symbol
  • 引用类型:object,Array,function
如何区分:
  • typeof(a) 用于返回值的类型,typeof一元运算符,用来返回操作数类型的字符串。有 "number"、"string"、"boolean"、"null"、"function" 和 "undefined"、"symble"、"object"
typeof(null)         		//object
typeof(1)				//number
typeof(undefiend)    		//undefiend
------------------------
typeof([])						//object
typeof({})						//object
  • instanceof 运算符是用来测试一个对象是否在其原型链原型构造函数的属性。

instanceof 其语法是object instanceof constructor返回布尔值类型

var arr = [1,2,3];  //创建一个数组对象
arr.prototype.constructor = Array;  //这一句是系统默认加上的
arr instanceof Array				//true

var a={b:"1"}
a instanceof Object 				//true

let a = function(){}
a instanceof Function					//true
Symbol介绍一下:“Symbol” 值表示唯一的标识符。Symbol 保证是唯一的。即使我们创建了许多具有相同描述的 Symbol,它们的值也是不同。描述只是一个标签,不影响任何东西。

Symbol("id")允许创建隐藏属性,不参与for。。。in循环

let id = Symbol("id");
let user = {
  name: "John",
  age: 30,
  [id]: 123
};

for (let key in user) alert(key); // name, age (no symbols)

// 使用 Symbol 任务直接访问
alert( "Direct: " + user[id] );//Direct:123

Object.keys(user) 也会忽略它们。
相反,Object.assign 会同时复制字符串和 symbol 属性:

let id = Symbol("id");
let user = {
  [id]: 123
};

let clone = Object.assign({}, user);

alert( clone[id] ); // 123

这里并不矛盾,就是这样设计的。这里的想法是当我们克隆或者合并一个 object 时,通常希望 所有 属性被复制(包括像 id 这样的 Symbol)。

详情可见现代JavaScript教程 https://zh.javascript.info/symbol

Q2: 介绍一下原型和原型链

  • js分为函数对象和普通对象,每个对象都有__proto__属性,但是只有函数对象才有prototype属性
  • Object、Function都是js内置的函数, 类似的还有我们常用到的Array、RegExp、Date、Boolean、Number、String
  • 属性__proto__是一个对象,它有两个属性,constructor和__proto__;
  • 原型对象prototype有一个默认的constructor属性,用于记录实例是由哪个构造函数创建;
  1. Person.prototype.constructor == Person // 准则1:原型对象(即Person.prototype)的constructor指向构造函数本身
  2. person01.proto == Person.prototype // 准则2:实例(即person01)的__proto__和原型对象指向同一个地方
    通过 proto 这个属性,而由这个属性组成的链,就叫做原型链。
    原型链的最顶端是 null ,往下是 Object 对象,而且只要是对象或函数类型都会有 proto 这个属性,
    原型对象的作用,是用来存放实例中共有的那部份属性、方法,可以大大减少内存消耗。
原型链的作用:
  • 实现继承:如果没有原型链,每个对象就都是孤立的,对象间就没有关联,所以原型链就像一颗树干,从而可以实现面对对象中的继承
  • 属性查找:首先在当前实例对象上查找,要是没找到,那么沿着 proto 往上查找
  • 实例类型判断:判断这个实例是否属于某类对象

Q3:基本数据类型和引用数据类型有什么区别

  • 基本类型:存储在栈内存中,因为基本类型的大小是固定,在栈内可以快速查找。
  • 引用类型:存储在堆内存中,因为引用类型的大小是不固定的,所以存储在堆内存中,然后栈内存中仅存储堆中的内存地址。
  • 基本数据类型:包括:null、undefined、number、string、boolean、symbol(es6)
    存放位置:内存中的栈区域中
    比较:值的比较,判断是否相等,如果值相等,就相等。一般使用=====进行比较
    拷贝:赋值(通过(=)赋值操作符 赋值),赋值完成后,两个变量之间就没有任何关系了,改变其中一个变量的值对另一个没有任何影响
  • 引用数据类型:
    包括:数组、对象、函数
    存放位置:内存的栈区域中存放变量和指针,堆区域存储实际的对象
    比较:是引用的比较(就是地址的比较,变量在栈内存中对应的指针地址相等就指向同一个对象)判断是否为同一个对象,示例如下
  • 浅拷贝:重新在堆内存中开辟一个空间,拷贝后新对象获得一个独立的基本数据类型数据,和原对象共用一个原对象内的引用类型数据,改变基本类型数据,两个对象互不影响,改变其中一个对象内的引用类型数据,另一个对象会受到影响
  • 深拷贝:不论是对象内的基本类型还是引用类型都被完全拷贝,拷贝后两个对象互不影响(JSON.parse(JSON.stringify(obj))

Q3:undefined和null的区别

唉,当时面试心情,

:"空值,未定义"
:"还有呢?"
......
:"没有了"😦

看一下正经答案吧:

null==undefiend///true
null====undefiend//false

null:null类型,代表空值,typeof null 是一个object,可以看作是一个特殊的对象值
undefined:undefined类型,当声明一个变量没有初始化的时候得到的是undefined
null表示"没有对象",即该处不应该有值。典型用法是:
(1) 作为函数的参数,表示该函数的参数不是对象。
(2) 作为对象原型链的终点。
undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。

参考阮一峰老师链接https://www.ruanyifeng.com/blog/2014/03/undefined-vs-null.html

Q4:介绍一下this:

Q5:介绍一个箭头函数

Q6:介绍一下promise(!!!!!重要)

Q7:setTimout

Q8:宏任务和微任务

Q9:js事件机制

Q10:闭包(!!!!重要)

Q11:跨域,怎么解决

Q12:JSONP怎么实现

Q13:项目优化

Q14:CDN用过吗?说一下

Q15:react:生命周期

Q16:react hooks生命周期

Q17:State是同步还是异步,为啥

Q18:介绍一下redux工作流程

Q19:react 优化性能:SCU,PurComponent,Memo

Q20:hoc高阶组件(--问的时候我都想死,笑死,根本没用过)

Q21:flex布局介绍一下

Q22: if。。else和switch。。case 对比,哪个性能高

Q23:map和forEach区别

Q24:普通函数和箭头函数的区别

Q25:变量提升

Q26:flex布局介绍下

Q27:如何实现垂直居中

Q28:如何实现左右排列

Q29:css实现元素垂直居中。

Q30:React。新旧生命周期对比,分别说出每个生命周期做了什么:

旧版: 挂载:

constructor():完成了React数据的初始化以及实现一些this的绑定。
componentWillMount():
render():渲染组件页面渲染执行的逻辑,render函数把jsx编译为函数并生成虚拟dom,然后通过其diff算法比较更新前后的新旧DOM树,并渲染更改后的节点。
componentDidMount():组件第一次渲染完成时执行的逻辑,此时DOM节点已经生成了。

更新:

componentWillReceiveProps(nextProps):接收父组件新的props时,重新渲染组件执行的逻辑。
shouldComponentUpdate(nextProps,nextState):在setState以后,state发生变化,组件会进入重新渲染的流程时执行的逻辑。在这个生命周期中return false可以阻止组件的更新,主要用于性能优化。
componentWillUpdate (nextProps,nextState):shouldComponentUpdate返回true以后,组件进入重新渲染的流程时执行的逻辑。
render():页面重新渲染
componentDidUpdate(prevProps,prevState):重新渲染后执行的逻辑。

卸载:

componentWillUnmount():组件的卸载前执行的逻辑,比如进行“清除组件中所有的setTimeout、setInterval等计时器”或“移除所有组件中的监听器removeEventListener”等操作。
新版

挂载:

constructor()

更新:

getDerivedStateFromProps(nextProps, prevState):新的 props 更新到相应的 state 上去。在这个过程中我们实际上是可以访问到当前props的,这样我们可能会对this.props做一些奇奇怪怪的操作,很可能会破坏 state 数据的单一数据源,导致组件状态变得不可预测。
schouldComponetUpdate():
render()
getSnapShotBeforeUpdate()
componentDidUpdata()

卸载:

componentWillUmount()
新旧对比:
使用getDerivedStateFromProps代替了旧的componentWillReceiveProps及componentWillMount。使用getSnapshotBeforeUpdate代替了旧的componentWillUpdate。

Q31:React hooks。生命周期:

useState, useEffect() 和 useLayoutEffect()

Q32:for in 和for of 区别:

for in 取 key;
for of 取 value;
for of 只能用于数组遍历,for in还可以用于对象属性的遍历

Q33:数组去重

Q34:class 怎么继承属性

Q35:数组方法

Q36:对象的方法

Q37:类型转换,一系列api

posted @ 2021-05-14 23:49  西柚_w  阅读(885)  评论(0编辑  收藏  举报