Web前端最全1(6),338页网易前端面试真题解析火爆全网

ES6

  • 列举常用的ES6特性:

  • 箭头函数需要注意哪些地方?

  • let、const、var

  • 拓展:var方式定义的变量有什么样的bug?

  • Set数据结构

  • 拓展:数组去重的方法

  • 箭头函数this的指向。

  • 手写ES6 class继承。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

微信小程序

  • 简单描述一下微信小程序的相关文件类型?

  • 你是怎么封装微信小程序的数据请求?

  • 有哪些参数传值的方法?

  • 你使用过哪些方法,来提高微信小程序的应用速度?

  • 小程序和原生App哪个好?

  • 简述微信小程序原理?

  • 分析微信小程序的优劣势

  • 怎么解决小程序的异步请求问题?

其他知识点面试

  • webpack的原理

  • webpack的loader和plugin的区别?

  • 怎么使用webpack对项目进行优化?

  • 防抖、节流

  • 浏览器的缓存机制

  • 描述一下二叉树, 并说明二叉树的几种遍历方式?

  • 项目类问题

  • 笔试编程题:

最后

技术栈比较搭,基本用过的东西都是一模一样的。快手终面喜欢问智力题,校招也是终面问智力题,大家要准备一下一些经典智力题。如果排列组合、概率论这些基础忘了,建议回去补一下。

组件状态管理

组件状态管理:如果组件中数据会变化 并影响⻚⾯内容 则组件需要拥有状态(state)并维护状态

类组件中的状态管理

class组件中的状态管理:

  • 使⽤state和setState维护状态

  • 使⽤setState⽅法更新状态

class组件实现定时器功能的实现方案:

  • state方式定义date【Component中定义了state 继承到了】

  • 定义constructor:构造函数

  • super:超级 实现继承 将继承的变量都带过来后就可以用state

  • componentDidMount中实现定时器:生命周期函数 组件挂载完成之后执行

  • componentWillUnmount:生命周期函数 组件将要卸载时执行【当前组件不存在】

src/pages/Home.js【创建⼀个Clock】

import React, { Component } from ‘react’

export default class Home extends React.Component {

// 定义constructor:构造函数

constructor(props) {

super(props) // super超级 实现继承 将继承的变量都带过来后就可以用state

// 使⽤state属性维护状态,在构造函数中初始化状态

this.state = { date: new Date() }

}

// 生命周期函数 组件挂载完成之后执行

componentDidMount() {

// 组件挂载时启动定时器每秒更新状态

this.timerID = setInterval(() => {

// 使⽤setState⽅法更新状态

this.setState({

date: new Date(),

})

}, 1000)

}

componentWillUnmount() {

// 组件卸载时停⽌定时器

clearInterval(this.timerID)

}

render() {

return

{this.state.date.toLocaleTimeString()}

}

}

拓展:setState特性讨论【setState是同步的还是异步的】

setState:是异步放在setState中进行处理 简单来说就是放到了一个数组里然后最后一起取值

setState格式:

//可传两个参数变量

setState((state,props)=>{})

// 可传函数

setState((state,props)=>{},callback)

⽤setState更新状态⽽不能直接修改

this.state.counter += 1; //错误的

setState是批量执⾏的 因此对同⼀个状态执⾏多次只起⼀次作⽤ 多个状态更新可以放在同⼀个setState中进⾏:

Q:假如couter初始值为0,执⾏三次以后其结果是多少?是1

componentDidMount() {

this.setState({ counter: this.state.counter + 1 })

this.setState({ counter: this.state.counter + 1 })

this.setState({ counter: this.state.counter + 1 })

}

src/pages/Home.js

import React, { Component } from “react”;

export default class Home extends Component {

constructor(props) {

super(props);

this.state = {

counter: 0,

};

// 给setCounter的this绑定 不然setCounter会找不到this.setState 或者ES6的箭头函数可以解决this指向问题

// this.setCounter = this.setCounter.bind(this);

}

// 箭头函数 解决this.setState找不到的问题

setCounter = () => {

this.setState({

counter: this.state.counter + 1,

});

this.setState({

counter: this.state.counter + 3,

});

console.log(“state”, this.state.counter);

};

render() {

const { counter } = this.state;//ES6解构赋值 直接取this.state中的date

return (

{counter}

{/* 函数setCounter */}

改变counter

);

}

}

setCounter:控制台打印的结果是0 页面的执行结果是3

  • 因为异步 控制台打印的结果是0【guess:先执行的普通js脚本后执行的this.setState】 页面的执行结果是第二次方法的执行结果3

  • 只执行了第二个setState 即每次点击只+3

setState的3种实现同步的方式

setState通常是异步的 因此如果要获取到最新状态值有以下三种⽅式:

setState实现同步的修改方案一:传递函数给setState⽅法

  • 函数传递状态的方式==》nextState实现同步更新【控制台未同步 页面执行同步了】

  • 回调函数的方式进行处理nextState

  • this.setState(nextState => {})中的nextState指上一个state

  • 是异步 当前状态会被保存起来 再用的时候 用函数的话就会直接获取上一个状态的State

setCounter = () => {

// nextState:存的state中的状态值

this.setState((nextState, props) => {

return {

counter: nextState.counter + 1,

};

});

this.setState((nextState, props) => {

return {

counter: nextState.counter + 3,

};

});

console.log(“state”, this.state.counter);

};

第一次执行结果是4 第二次执行结果是8:两个setState都执行了 分别+1+3即每次+4

setState实现同步的修改方案二:使⽤定时器

  • setTimeout实现同步更新【控制台同步 页面执行也同步】

  • setTimeout定时器是异步的

setCounter = () => {

setTimeout(() => {

this.setState({

counter: this.state.counter + 3,

});

console.log(“sta”, this.state.counter);

}, 0);

};

setState实现同步的修改方案三:原⽣事件中修改状态

  • 原生事件上进行绑定 实现同步更新【控制台同步 页面执行也同步】

componentDidMount() {

// getElementsByTagName得到的是一个数组

document.getElementsByTagName(“button”)[0].addEventListener(

“click”,

() => {

this.setState({

counter: this.state.counter + 2,

});

console.log(“sta”, this.state.counter);

},

0,

);

// document.body.addEventListener(‘click’, this.changeValue, false)

}

changeValue = () => {

this.setState({ counter: this.state.counter + 7 })

console.log(this.state.counter)

},

总结: setState只有在合成事件和钩⼦函数中是异步的,在原⽣事件和setTimeout、setInterval中都是同步的。

函数组件中的状态管理

function组件:

  • function组件本身没有state 也没有生命周期函数[钩子]

  • state特别庞大时建议用class组件

  • 函数组件通过hooks[钩子]api维护状态

function组件实现定时器功能的实现方案:

  • 引入useState及useEffect函数

src/pages/User.js【前面在class组件中实现了定时器的功能 now在function组件中实现定时器的功能】

import React, { useState, useEffect } from “react”;

//hooks

export default function User() {

// const date = new Date();

const [date, setDate] = useState(new Date());//useState初始化值

const [date2, setDate2] = useState(new Date());//初始化值2

// useEffect动起来

useEffect(() => {

const timerId = setInterval(() => {

setDate(new Date());

}, 1000);

return () => clearInterval(timerId);//组件卸载的时候清除定时器

});

return (

我是user页面

{date.toLocaleTimeString()}

);

}

hooks api后⾯课程会继续深⼊讲解

事件回调函数注意绑定this指向,常⻅三种⽅法:

  • 构造函数中绑定并覆盖:

this.change = this.change.bind(this)

  • ⽅法定义为箭头函数:

onChange={()=>this.change()}

react是单向数据流 vue是双向数据流

React:react⾥遵循单项数据流 没有双向绑定 实现输⼊框要设置value和onChange 称为受控组件

Vue:vue是双向数据流 是语法糖

React事件处理

React的事件处理:React中使⽤onXX写法来监听事件 onClick onChange

src\pages\Search.js【例:⽤户输⼊事件】

import React, { Component } from “react”;

export default class Search extends Component {

/* state = {name: “”,}; */

// 建议用constructor super形式 编译结果不一样

constructor(props) {

super(props);//继承Component中的props

this.state = {

name: “”,

};

}

// 使⽤箭头函数,不需要指定回调函数this,且便于传递参数

handle = () => {

const { tellme } = this.props;// 解构赋值 取出tellme

tellme(“我是search”);

console.log(“handle”);

};

change = event => {

let value = event.target.value;

// setState异步

this.setState({

name: value,

});

console.log(“change”, this.state.name);//打印出上一次操作的结果

};

render() {

const { name } = this.state;

const { userInfo } = this.props.store;

console.log(“this”, this);

return (

我是Search页面

{userInfo.userName}

click

);

}

}

组件通信

  • Props属性传递:Props属性传递可⽤于⽗⼦组件相互通信

// 父组件 index.js

ReactDOM.render(,

document.querySelector(‘#root’));

// 子组件 App.js

{this.props.title}

src\App.js

import React from “react”;

import logo from “./logo.svg”;

import “./App.css”;

import Search from “./pages/Search”;

const store = {

userInfo: {

userName: “xiaoming”,

},

};

function tellme(msg) {

console.log(“tellme”, msg);

}

function App() {

return (

);

}

export default App;

状态提升:如果⽗组件传递的是函数,则可以把⼦组件信息传⼊⽗组件,这个常称为状态提升

// StateMgt.js

< Clock change = {this.onChange}/>

// Clock

this.timerID = setInterval(() = >{

this.setState({

date: new Date()

},

() = >{

// 每次状态更新就通知⽗组件

this.props.change(this.state.date);

});

},1000);

  • context【上下文】:跨层级组件之间通信【多层】

主要⽤于组件库开发中,后⾯组件化内容中详细介绍 建议不要在项目中滥用

  • redux:类似vuex,⽆明显关系的组件间通信

后⾯全家桶部分详细介绍

React V16.3之前的⽣命周期

  • defaultProps:默认参数 设置组件的默认属性

  • constructor:构造函数 继承时用到super 定义状态值放在state中 设置组件的初始化状态

  • componentWillMount():组件将要挂载之前 即将被废弃的声明周期

  • render():组件渲染现在时态

  • componentDidMount() :组件挂载之后 组件已经被渲染到页面中后触发

  • componentWillUnmount():组件将要卸载之前

  • componentWillUpdate():组件更新之前

  • componentDidUpdate():组件更新之后

  • componentWillUnmount():组件卸载之前

  • shouldComponentUpdate():组件是否应该render 值是更新的只是没有render

src\pages\LifeCycle.js【验证16.3版本的生命周期:写在class组件中】

import React, { Component } from “react”;

export default class LifeCycle extends Component {

constructor(props) {

super(props);

this.state = {

counter: 0,

};

console.log(“执行constructor构造函数”, this.state.counter);

}

// 组件将要挂载 挂载之前执行的内容

componentWillMount() {

console.log(“componentWillMount组件将要挂载”, this.state.counter);

}

// 组件挂载之后

componentDidMount() {

console.log(“componentDidMount组件挂载之后”, this.state.counter);

}

//组件卸载之前

componentWillUnmount() {

console.log(“componentWillUnmount”, this.state.counter);

}

// 组件更新之前

componentWillUpdate() {

console.log(“componentWillUpdate更新之前”, this.state.counter);

}

// 组件更新之后

componentDidUpdate() {

console.log(“componentDidUpdate更新之后”, this.state.counter);

}

// 组件是否应该更新 更新局部 nextState更新后的值

shouldComponentUpdate(nextProps, nextState) {

const { counter } = this.state;//更新之前的值

console.log(“shouldComponentUpdate组件是否应该更新”, counter, nextState.counter);

return counter != 5;//不是5才执行更新 避免不必要的更新

}

setCounter = () => {

this.setState({

counter: this.state.counter + 1,

});

};

// setState会重新render

render() {

const { counter } = this.state;

console.log(“render”, counter);

return (

我是LifeCycle页面

{counter}

改变counter

{!!(counter % 2) && }

);

}

}

// Foo组件

class Foo extends Component {

componentWillUnmount() {

//组件卸载之前

console.log(" Foo组件卸载之前 componentWillUnmount");

}

render() {

return

我是Foo组件
;

}

}

React V16.4之后的⽣命周期:

V17可能会废弃的三个⽣命周期函数:⽤getDerivedStateFromProps替代,⽬前使⽤的话加上UNSAFE_:

  • componentWillMount使用示例:UNSAFE_componentWillMount()

  • componentWillReceiveProps(nextProps)

  • componentWillUpdate(nextProps, nextState)

引⼊两个新的⽣命周期函数:

  • static getDerivedStateFromProps

  • getSnapshotBeforeUpdate

变更缘由:原来(React v16.0前)的⽣命周期在React v16推出的Fiber之后就不合适了,因为如果要开启async rendering,在render函数之前的所有函数,都有可能被执⾏多次。

原来(React v16.0前)的⽣命周期有哪些是在render前执⾏的呢?

  • componentWillMount

  • componentWillReceiveProps

  • shouldComponentUpdate

  • componentWillUpdate

如果开发者开了async rendering,⽽且⼜在以上这些render前执⾏的⽣命周期⽅法做AJAX请求的话,那AJAX将被⽆谓地多次调⽤。。。明显不是我们期望的结果。⽽且在componentWillMount⾥发起AJAX,不管多快得到结果也赶不上⾸次render,⽽且componentWillMount在服务器端渲染也会被调⽤到(当然,也许这是预期的结果),这样的IO操作放在componentDidMount⾥更

合适。

禁⽌不能⽤⽐劝导开发者不要这样⽤的效果更好,所以除了shouldComponentUpdate,其他在render函数之前的所有函数(componentWillMount,componentWillReceiveProps,

componentWillUpdate)都被getDerivedStateFromProps替代。

也就是⽤⼀个静态函数getDerivedStateFromProps来取代被deprecate的⼏个⽣命周期函数,就是强制开发者在render之前只做⽆副作⽤的操作,⽽且能做的操作局限在根据props和state决定新的state

React v16.0刚推出的时候,是增加了⼀个componentDidCatch⽣命周期函数,这只是⼀个增量式修改,完全不影响原有⽣命周期函数;但是,到了React v16.3,⼤改动来了,引⼊了两个新的⽣命周期函数。

新引⼊了两个新的⽣命周期函数:

  • getSnapshotBeforeUpdate

  • getDerivedStateFromProps

getDerivedStateFromProps会在调⽤ render ⽅法之前调⽤,并且在初始挂载及后续更新时都会被调⽤。它应返回⼀个对象来更新state,如果返回 null 则不更新任何内容。

请注意,不管原因是什么,都会在每次渲染前触发此⽅法。这与UNSAFE_componentWillReceiveProps形成对⽐,后者仅在⽗组件重新渲染时触发,⽽不是在内部调⽤ setState 时。链接

static getDerivedStateFromProps(props, state)

React v16.3 的⽣命周期图

React v16.3:这样的话理解起来有点乱,在React v16.4中改正了这⼀点,让getDerivedStateFromProps⽆论是Mounting还是Updating,也⽆论是因为什么引起的Updating,全部都会被调⽤,具体可看Reactv16.4 的⽣命周期图。

React v16.4后的getDerivedStateFromProps

static getDerivedStateFromProps(props, state) 在组件创建时和更新时的render⽅法之前调⽤,它应该返回⼀个对象来更新状态,或者返回null来不更新任何内容。

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps, prevState)

在render之后,在componentDidUpdate之前。getSnapshotBeforeUpdate()在最近⼀次渲染输出(提交到DOM 节点)之前调⽤。它使得组件能在发⽣更改之前从 DOM 中捕获⼀些信息(例如,滚动位置)。此⽣命周期的任何返回值将作为参数传递给 componentDidUpdate()。此⽤法并不常⻅,但它可能出现在 UI 处理中,如需要以特殊⽅式处理滚动位置的聊天线程等。应返回 snapshot 的值(或 null)。

官网给的例⼦

class ScrollingList extends React.Component {

constructor(props) {

super(props);

this.listRef = React.createRef();

}

getSnapshotBeforeUpdate(prevProps, prevState) {

//我们是否要添加新的 items 到列表?

// 捕捉滚动位置,以便我们可以稍后调整滚动.

if (prevProps.list.length < this.props.list.length) {

const list = this.listRef.current;

return list.scrollHeight - list.scrollTop;

}

return null;

}

componentDidUpdate(prevProps, prevState, snapshot) {

//如果我们有snapshot值, 我们已经添加了 新的items.

// 调整滚动以⾄于这些新的items 不会将旧items推出视图。

// (这边的snapshot是 getSnapshotBeforeUpdate⽅法的返回值)

if (snapshot !== null) {

const list = this.listRef.current;

list.scrollTop = list.scrollHeight - snapshot;

}

}

render() {

return ( < div ref = {this.listRef} > {/* …contents… */} < /div>

);

}

在上述示例中,重点是从 getSnapshotBeforeUpdate 读取scrollHeight 属性,因为 “render” 阶段⽣命周期(如 render)和 “commit” 阶段⽣命周期(如 getSnapshotBeforeUpdate 和componentDidUpdate)之间可能存在延迟。

getDerivedStateFromError、componentDidCatch可以参考官⽹,内容很详细,此处不再赘述。

验证⽣命周期

范例:创建Lifecycle.js

import React, { Component } from ‘react’

/*

V17可能会废弃的三个⽣命周期函数⽤getDerivedStateFromProps替代,⽬前使⽤的话加上UNSAFE_:

  • componentWillMount

  • componentWillReceiveProps

  • componentWillUpdate

*/

export default class LifeCycle extends Component {

constructor(props) {

super(props)

this.state = {

counter: 0,

}

console.log(‘constructor’, this.state.counter)

}

static getDerivedStateFromProps(props, state) {

// getDerivedStateFromProps 会在调⽤ render ⽅法之前调⽤,

//并且在初始挂载及后续更新时都会被调⽤。

//它应返回⼀个对象来更新 state,如果返回 null 则不更新任何内容。

const { counter } = state

console.log(‘getDerivedStateFromProps’, counter)

return counter < 8 ? null : { counter: 0 }

}

getSnapshotBeforeUpdate(prevProps, prevState) {

const { counter } = prevState

console.log(‘getSnapshotBeforeUpdate’, counter)

return null

}

/* UNSAFE_componentWillMount() {

//不推荐,将会被废弃

console.log(“componentWillMount”,

this.state.counter);

} */

componentDidMount() {

console.log(‘componentDidMount’, this.state.counter)

}

componentWillUnmount() {

//组件卸载之前

console.log(‘componentWillUnmount’, this.state.counter)

}

/* UNSAFE_componentWillUpdate() {

//不推荐,将会被废弃

console.log(“componentWillUpdate”,

this.state.counter);

} */

componentDidUpdate() {

console.log(‘componentDidUpdate’, this.state.counter)

}

shouldComponentUpdate(nextProps, nextState) {

const { counter } = this.state

console.log(‘shouldComponentUpdate’, counter, nextState.counter)

return counter !== 5

}

setCounter = () => {

this.setState({

counter: this.state.counter + 1,

})

}

render() {

const { counter } = this.state

console.log(‘render’, this.state)

return (

我是LifeCycle⻚⾯

{counter}

改变 counter

{/* {!!(counter % 2) && } */}

)

}

}

class Foo extends Component {

UNSAFE_componentWillReceiveProps(nextProps) {

//不推荐,将会被废弃

// UNSAFE_componentWillReceiveProps() 会在已挂载的组件接收新的 props 之前被调⽤

console.log(‘Foo componentWillReceiveProps’)

}

componentWillUnmount() {

//组件卸载之前

console.log(’ Foo componentWillUnmount’)

}

render() {

return (

我是Foo组件

Foo counter: {this.props.counter}

)

}

最后

面试一面会问很多基础问题,而这些基础问题基本上在网上搜索,面试题都会很多很多。最好把准备一下常见的面试问题,毕竟面试也相当与一次考试,所以找工作面试的准备千万别偷懒。面试就跟考试一样的,时间长了不复习,现场表现肯定不会太好。表现的不好面试官不可能说,我猜他没发挥好,我录用他吧。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

96道前端面试题:

常用算法面试题:

前端基础面试题:
内容主要包括HTML,CSS,JavaScript,浏览器,性能优化

ntUpdate’, counter, nextState.counter)

return counter !== 5

}

setCounter = () => {

this.setState({

counter: this.state.counter + 1,

})

}

render() {

const { counter } = this.state

console.log(‘render’, this.state)

return (

我是LifeCycle⻚⾯

{counter}

改变 counter

{/* {!!(counter % 2) && } */}

)

}

}

class Foo extends Component {

UNSAFE_componentWillReceiveProps(nextProps) {

//不推荐,将会被废弃

// UNSAFE_componentWillReceiveProps() 会在已挂载的组件接收新的 props 之前被调⽤

console.log(‘Foo componentWillReceiveProps’)

}

componentWillUnmount() {

//组件卸载之前

console.log(’ Foo componentWillUnmount’)

}

render() {

return (

我是Foo组件

Foo counter: {this.props.counter}

)

}

最后

面试一面会问很多基础问题,而这些基础问题基本上在网上搜索,面试题都会很多很多。最好把准备一下常见的面试问题,毕竟面试也相当与一次考试,所以找工作面试的准备千万别偷懒。面试就跟考试一样的,时间长了不复习,现场表现肯定不会太好。表现的不好面试官不可能说,我猜他没发挥好,我录用他吧。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

96道前端面试题:

  • [外链图片转存中…(img-YzhWHoIv-1715168194755)]

常用算法面试题:

  • [外链图片转存中…(img-YbMhpMAK-1715168194755)]

前端基础面试题:
内容主要包括HTML,CSS,JavaScript,浏览器,性能优化

  • [外链图片转存中…(img-1divthsA-1715168194756)]
  • 13
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值