小白准备转行学习前端,有大神可以提一些建议吗
学习是以兴趣为前提的,你要对你所要学的内容产生兴趣,这样你才会花心思去学习。这和是不是小白没关系的,对于小白而言,在学习过程中就需要更努力,多花时间和心思没有什么是学不会的。
自学方法:
1、作为一个初学者,你必须明确系统的学习方案,我建议一定有一个指导的人,全靠自己学,放弃的几率非常大,在你对于web前端还没有任何概念的时候,需要一个人领进门,之后就都靠自己钻研,第一步就是确定web前端都需要哪些内容,并且在多少时间内学完,建议时间6个月保底。
2、视频为主,书为辅。很多初学者在学习前端的时候非常喜欢去买书,但是最后的结果是什么?看来看去什么都不会写,所以在这里给大家提醒,书可以看,但是是在建立于你已经对于某个知识点有了具体操作的执行后,在用书去巩固概念,这样更加利于你对于知识的理解。
3、对于学习技术来讲,掌握一个学习方法是非常重要的,其实对于学习web前端来讲,学习方法确实很多都是相通的,一旦学习方法不对,可能就会造成“方法不对,努力白费”。其实关于这方面还是很多的,我就简单说个例子,有的人边听课边跟着敲代码,这样就不对,听课的时候就专心听,做题的时候就专心做题,这都是过来人的经验,一定要听。根据每个人的不同,可能学习方法也会有所出路,找到适合你自己的学习法方法是学习的前提。
4、不建议自己一个人瞎学,在我了解学习编程的这些人来看,从零基础开始学并且最后成功做这份工作的其实并没有几个,我觉得大部分原因就是因为他们都不了解web前端是干什么的,学什么的,就盲目的买书看,到处找视频看,最后看着看着就放弃了,所以我建议初学者在没有具体概念之前,还是找有经验的人请教一下,聊过之后你就会知道web前端具体是干什么的,该怎么学,这是我个人的小建议,可以不采纳。
自学路线:
第1阶段:前端页面重构(4周)
内容包含了:(PC端网站布局项目、HTML5+CSS3基础项目、WebApp页面布局项目)
第2阶段:JavaScript高级程序设计(5周)
内容包含:(原生JavaScript交互功能开发项目、面向对象进阶与ES5/ES6应用项目、JavaScript工具库自主研发项目)
第3阶段:PC端全栈项目开发(3周)
内容包含:(jQuery经典交互特效开发、HTTP协议、Ajax进阶与PHP/JAVA开发项目、前端工程化与模块化应用项目、PC端网站开发项目、PC端管理信息系统前端开发项目)
第4阶段:移动端项目开发(6周)
内容包含:(Touch端项目、微信场景项目、应用Angular+Ionic开发WebApp项目、应用Vue.js开发WebApp项目、应用React.js开发WebApp项目)
第5阶段:混合(Hybrid,ReactNative)开发(1周)
内容包含:(微信小程序开发、ReactNative、各类混合应用开发)
第6阶段:NodeJS全栈开发(1周)
内容包括:(WebApp后端系统开发、一、NodeJS基础与NodeJS核心模块二、Express三、noSQL数据库)
视频教程:
网页链接
网页链接
如果你对于学习前端有任何不懂的可以随时来问我,如果没有比较好的教程,也可以问我要。
2022年前端React的100道面试题的第17题:Ref的使用
React17 中对 Ref 的正确使用方式有哪些?
绑定 Ref 的方式
注意:上面的所有方式,如果是给组件传 ref 属性,则需要对此组件进行 Refs 转发至具体的 HTML 元素。
回调 Refs 用于组件时
因常规函数和 class 组件不接收 ref 参数,且 props 中也不存在 ref 。因此回调 Refs 仅用于 HTML DOM 元素,如果给组件传函数 Refs 应通过 props 透传。
例如下面的方式:
回调 Refs 的参数
回调函数方式的执行时机为:
https://zh-hans.reactjs.org/docs/forwarding-refs.html
https://zh-hans.reactjs.org/docs/refs-and-the-dom.html
搜索《考试竞技》微信小程序
前端常见面试题
前端开发可能问到的问题:
自我介绍(一定要对项目很熟悉)
ui-app web前端技术体系?
响应式怎么做?
render跟状态的差异
类组件的生命周期?
阻止冒泡,阻止事件默认行为
文本垂直居中。 line-height设置为元素高度。
用reduce讲数组中的对象进行合并
解释localstorage sessionstorage cookie
eventbus满足event.on(’eventname’, callback)
display有几个值?默认值?
position有几个值?默认值?
div水平垂直居中?
position有哪些值
react相关问题(概念理解、通讯组件等)、react常用内置
React-router
html+css
页面增删改查
position的值 absolute relative fixed static
工作中是怎么联调和上线的(现场想合适的前后端联调方式,能和webpack环境切换联系起来)
antd的Form shouldUpdate增量更新方式,性能优化。
对Hooks的理解
3:操作dom点击事件向服务器上传数据,在上传未完成之前不可重复操作事件
4:日期格式化,日期不足前两位补0(2021-06-06 06:06:00)
用css写一个布局,左侧固定宽度,右侧自适应
你看
2022年前端React的100道面试题的第12题:区分props和state
对 props 和 state 设计理解正常的是?
A. 它们都是纯 JS 对象。
B. props 只能来自父级,组件本身始终无法设置。
C. 只有在 state 变化触发时,才会触发组件更新渲染。
D. props 是一种将数据从父级传递给子级的方式, state 仅用于交互性,即随时间变化的数据。
A、D
纠错
B. 如果选项是 ” props 只能来自父级,组件本身无法更新。“,那么就是正确的,是不能修改,而非不能设置。一个组件可以有默认的 props,也可以通过 defaultProps 设置默认值。
C. props 和 state 的变化都会触发组件更新渲染 。
它们都是用来保存信息的,这些信息可以控制组件的渲染输出。
而它们的一个重要的不同点就是: props 是传递 给 组件的(类似于函数的形参),而 state 是在组件 内 被组件自己管理的(类似于在一个函数内声明的变量)。
props
默认情况下,组件没有状态。下面是以函数组件为例,最简单的参数:
props 由父组件设置的信息,尽管可以设置默认值,并且不能改变它。
state
主要用于用户的事件状态的管理,它应是一个可序列化的数据。它允许组件进行初始化、更改和使用的“私有”信息。
默认值
从父级组件传入的 props 值,和 state 初始值都会覆盖组件内定义的默认值。
下面是 props 的初始化示例:
下面是 state 的初始化示例:
记一些面试问过的题和搜到的答案
1. diff算法
传统 diff 算法其时间复杂度最优解是 O(n^3),那么如果有 1000 个节点,则一次 diff 就将进行 10 亿次比较,这显然无法达到高性能的要求。而 React 通过大胆的假设,并基于假设提出相关策略,成功的将 O(n^3) 复杂度的问题转化为 O(n) 复杂度的问题。
tree diff
React 只对虚拟 DOM 树进行分层比较,不考虑节点的跨层级比较
React 通过 updateDepth 对虚拟 Dom 树进行层级控制,只会对相同颜色框内的节点进行比较,根据对比结果,进行节点的新增和删除。如此只需要遍历一次虚拟 Dom 树,就可以完成整个的对比
component diff
React 是基于组件构建的,对于组件间的比较所采用的策略如下:
如果是同类型组件,首先使用 shouldComponentUpdate()方法判断是否需要进行比较,如果返回true,继续按照 React diff 策略比较组件的虚拟 DOM 树,否则不需要比较
如果是不同类型的组件,则将该组件判断为 dirty component,从而替换整个组件下的所有子节点
对于不同类型的组件,默认不需要进行比较操作,直接重新创建。
对于同类型组件, 通过让开发人员自定义shouldComponentUpdate()方法来进行比较优化,减少组件不必要的比较。如果没有自定义,shouldComponentUpdate()方法默认返回true,默认每次组件发生数据(state & props)变化时,都会进行比较。
element diff
element diff 涉及三种操作:移动、创建、删除。element diff 就是通过唯一 key 来进行 diff 优化,通过复用已有的节点,减少节点的删除和创建操作。
不使用key:React 对新老同一层级的子节点对比,发现新集合中的 B 不等于老集合中的 A,于是删除 A,创建 B,依此类推,直到删除 D,创建 C。这会使得相同的节点不能复用,出现频繁的删除和创建操作,从而影响性能。
使用key:React 首先会对新集合进行遍历,通过唯一 key 来判断老集合中是否存在相同的节点,如果没有则创建,如果有的,则判断是否需要进行移动操作。并且 React 对于移动操作也采用了比较高效的算法,使用了一种顺序优化手段,这里不做详细讨论。
如何进行 diff
React 是基于组件构建的,首先可以将整个虚拟 DOM 树,抽象为 React 组件树(每一个组件又是由一颗更小的组件树构成,依次类推),将 React diff 策略应用比较这颗组件树,若其中某个组件需要进行比较,将这个组件看成一颗较小的组件树,继续用 React diff 策略比较这颗较小的组件树,依次类推,直到层次遍历完所有的需要比较的组件
React 通过大胆的假设,制定对应的 diff 策略,将 O(n3) 复杂度的问题转换成 O(n) 复杂度的问题
通过分层对比策略,对 tree diff 进行算法优化
通过相同类生成相似树形结构,不同类生成不同树形结构以及shouldComponentUpdate策略,对 component diff 进行算法优化
通过设置唯一 key 策略,对 element diff 进行算法优化
2. 虚拟dom
虚拟 DOM (Virtual DOM )实际上它只是一层对真实DOM的抽象,以JavaScript 对象 (VNode 节点) 作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作使这棵树映射到真实环境上
在Javascript对象中,虚拟DOM 表现为一个 Object对象。并且最少包含标签名 (tag)、属性 (attrs) 和子元素对象 (children) 三个属性,不同框架对这三个属性的名命可能会有差别
创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应
你用传统的原生api或jQuery去操作DOM时,浏览器会从构建DOM树开始从头到尾执行一遍流程
当你在一次操作时,需要更新10个DOM节点,浏览器没这么智能,收到第一个更新DOM请求后,并不知道后续还有9次更新操作,因此会马上执行流程,最终执行10次流程
而通过VNode,同样更新10个DOM节点,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地的一个js对象中,最终将这个js对象一次性attach到DOM树上,避免大量的无谓计算
3. hooks如何处理页面渲染
4. setState同步异步
由React控制的事件处理程序,以及生命周期函数调用setState不会同步更新state 。
在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用setState不会同步更新this.state,除此之外的setState调用会同步执行this.state。所谓“除此之外”,指的是绕过React通过addEventListener直接添加的事件处理函数,还有通过setTimeout/setInterval产生的异步调用
异步下多个setState调用会合并处理
第一个函数调用更新state,第二个函数是更新完之后的回调
/* 函数式用法*/
this.setState((state, props) =》 {
return {
count: state.count + 1
}
})
5. ts的初次使用
第一步:全局安装ts npm i -g typescript
第二步:创建tsconfig.json tsc –init
第三步: 安装开发环境依赖 npm install –save-dev typescript @types/react @types/react-dom ts-loader
第四步:修改webpack.config.js
module.exports = {
context: …,
entry: …,
output: …,
// 添加resolve
resolve: {
extensions:
},
module: {
loaders: [
// 增加新的loader
{
test: /\.tsx?$/,
loaders:
},
…
]
},
plugins: …
};
关于.tsx文件
如果.ts文件中包含jsx,则需要将.ts文件改成.tsx文件
需要引用.tsx文件时,不用加扩展名,import xxx from ‘./xxx’;,而引用.jsx文件,是需要加扩展名的
.tsx文件中,React和ReactDOM不支持default import,需要进行修改
6. useRef的用法
// useRef,返回一个可变的ref对象
const refContainer = useRef(initialValue);
5.26 涂鸦智能
1. useMemo 和useCallback
// useMemo,返回一个memoized值,只有第二个参数发生变化时才会重新计算。类似 useCallback。
function App () {
const = useState(0)
const add = useMemo(() =》 {
return count + 1
}, )
return (
《div》
点击次数: { count }
《br/》
次数加一: { add }
《button onClick={() =》 { setCount(count + 1)}}》点我《/button》
《/div》
)
}
上面的例子中,useMemo 也支持传入第二个参数,用法和 useEffect 类似
不传数组,每次更新都会重新计算
空数组,只会计算一次
依赖对应的值,当对应的值发生变化时,才会重新计算(可以依赖另外一个 useMemo 返回的值)
需要注意的是,useMemo 会在渲染的时候执行,而不是渲染之后执行,这一点和 useEffect 有区别,所以 useMemo 不建议有 副作用相关的逻辑
useCallback是什么呢,可以说是useMemo的语法糖,能用useCallback实现的,都可以使用useMemo,useCallback 的第二个参数和useMemo一样,没有区别. 在 react 中我们经常面临一个子组件渲染优化的问题, 尤其是在向子组件传递函数props时,每次render都会创建新函数,导致子组件不必要的渲染,浪费性能,这个时候,就是useCallback的用武之地了,useCallback可以保证,无论render多少次,我们的函数都是同一个函数,减小不断创建的开销,具体如何使用看下面例子
const onClick = useMemo(() =》 {
return () =》 {
console.log(’button click’)
}
}, )
const onClick = useCallback(() =》 {
console.log(’button click’)
}, )
// useCallback,返回一个memoized函数,第二个参数类似useEffect,只有参数变化时才会更改。
const memoizedCallback = useCallback(
() =》 {
doSomething(a, b);
},
,
);
2. ts的interface和type的区别
首先,interface只能表示function,object和class类型,type除了这些类型还可以表示其他类型
interface A{name:string;
add:()=》void;
}
interface B{():void}
type C=()=》number;
type D=string;
type E={name:string,age:number}
interface可以合并同名接口,type不可以
interface A{name:string}
interface A{age:number}
var x:A={name:’xx’,age:20}
interface可以继承interface,继承type,使用extends关键字,type也可继承type,也可继承interface,使用&
interface A{name:string}
interface B extends A{age:number}
type C={sex:string}
interface D extends C{name:string}
type E={name:string}&C
type F ={age:number}&A
还有类可以实现接口,也可以实现type
interface A{name:string;add:()=》void}
type B={age:number,add:()=》void}
class C implements A{
name:’xx’
add(){console.log(’类实现接口’)}
}
class D implements B{
age:20
add(){console.log(’类实现type’)}
}
计算属性:type 支持, interface 不支持。
总的来说,公共的用 interface 实现,不能用 interface 实现的再用 type 实现。主要是一个项目最好保持一致。
前端经典面试题(60道前端面试题包含JS、CSS、React、浏览器等)
防抖
节流
误区:我们经常说get请求参数的大小存在限制,而post请求的参数大小是无限制的。
实际上HTTP 协议从未规定 GET/POST 的请求长度限制是多少。对get请求参数的限制是来源与浏览器或web服务器,浏览器或web服务器限制了url的长度。为了明确这个概念,我们必须再次强调下面几点:
补充补充一个get和post在缓存方面的区别:
可从IIFE、AMD、CMD、CommonJS、UMD、webpack(require.ensure)、ES Module、
vue和react都是采用diff算法来对比新旧虚拟节点,从而更新节点。在vue的diff函数中(建议先了解一下diff算法过程)。在交叉对比中,当新节点跟旧节点 头尾交叉对比 没有结果时,会根据新节点的key去对比旧节点数组中的key,从而找到相应旧节点(这里对应的是一个key =》 index 的map映射)。如果没找到就认为是一个新增节点。而如果没有key,那么就会采用遍历查找的方式去找到对应的旧节点。一种一个map映射,另一种是遍历查找。相比而言。map映射的速度更快。vue部分源码如下:
创建map函数
遍历寻找
在React中, 如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用setState不会同步更新this.state,除此之外的setState调用会同步执行this.state 。所谓“除此之外”,指的是绕过React通过addEventListener直接添加的事件处理函数,还有通过setTimeout/setInterval产生的异步调用。
**原因:**在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是, 有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state 。
虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能。
具体实现步骤如下:
用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了。
结构:display:none: 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击, visibility: hidden:不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击 opacity: 0: 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击
继承:display: none:是非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。visibility: hidden:是继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。
性能:displaynone : 修改元素会造成文档回流,读屏器不会读取display: none元素内容,性能消耗较大 visibility:hidden: 修改元素只会造成本元素的重绘,性能消耗较少读屏器读取visibility: hidden元素内容 opacity: 0 :修改元素会造成重绘,性能消耗较少
联系:它们都能让元素不可见
常用的一般为三种 .clearfix , clear:both , overflow:hidden ;
比较好是 .clearfix ,伪元素万金油版本,后两者有局限性.
clear:both :若是用在同一个容器内相邻元素上,那是贼好的,有时候在容器外就有些问题了, 比如相邻容器的包裹层元素塌陷
overflow:hidden :这种若是用在同个容器内,可以形成 BFC 避免浮动造成的元素塌陷
概念:将多个小图片拼接到一个图片中。通过 background-position 和元素尺寸调节需要显示的背景图案。
优点:
缺点:
block 元素特点:
1.处于常规流中时,如果 width 没有设置,会自动填充满父容器 2.可以应用 margin/padding 3.在没有设置高度的情况下会扩展高度以包含常规流中的子元素 4.处于常规流中时布局时在前后元素位置之间(独占一个水平空间) 5.忽略 vertical-align
inline 元素特点
1.水平方向上根据 direction 依次布局
2.不会在元素前后进行换行
3.受 white-space 控制
4. margin/padding 在竖直方向上无效,水平方向上有效
5. width/height 属性对非替换行内元素无效,宽度由元素内容决定
6.非替换行内元素的行框高由 line-height 确定,替换行内元素的行框高由 height , margin , padding , border 决定 7.浮动或绝对定位时会转换为 block 8. vertical-align 属性生效
GIF :
JPEG :
PNG :
七种数据类型
(ES6之前)其中5种为基本类型: string , number , boolean , null , undefined ,
ES6出来的 Symbol 也是原始数据类型 ,表示独一无二的值
Object 为引用类型(范围挺大),也包括数组、函数,
输出结果是:
工厂模式
简单的工厂模式可以理解为解决多个相似的问题;
单例模式
只能被实例化(构造函数给实例添加属性与方法)一次
沙箱模式
将一些函数放到自执行函数里面,但要用闭包暴露接口,用变量接收暴露的接口,再调用里面的值,否则无法使用里面的值
1.字面量
2.Object构造函数创建
3.使用工厂模式创建对象
4.使用构造函数创建对象
HTML中与javascript交互是通过事件驱动来实现的,例如鼠标点击事件onclick、页面的滚动事件onscroll等等,可以向文档或者文档中的元素添加事件侦听器来预订事件。想要知道这些事件是在什么时候进行调用的,就需要了解一下“事件流”的概念。
什么是事件流:事件流描述的是从页面中接收事件的顺序,DOM2级事件流包括下面几个阶段。
addEventListener : addEventListener 是DOM2 级事件新增的指定事件处理程序的操作,这个方法接收3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
IE只支持事件冒泡 。
获取一个对象的原型,在chrome中可以通过__proto__的形式,或者在ES6中可以通过Object.getPrototypeOf的形式。
那么Function.proto是什么么?也就是说Function由什么对象继承而来,我们来做如下判别。
我们发现Function的原型也是Function。
我们用图可以来明确这个关系:
这里来举个栗子,以 Object 为例,我们常用的 Object 便是一个构造函数,因此我们可以通过它构建实例。
则此时, 实例为instance , 构造函数为Object ,我们知道,构造函数拥有一个 prototype 的属性指向原型,因此原型为:
这里我们可以来看出三者的关系:
在 JS 中,继承通常指的便是 原型链继承 ,也就是通过指定原型,并可以通过原型链继承原型上的属性或者方法。
在函数式编程中,函数是一等公民。那么函数柯里化是怎样的呢?
函数柯里化指的是将能够接收多个参数的函数转化为接收单一参数的函数,并且返回接收余下参数且返回结果的新函数的技术。
函数柯里化的主要作用和特点就是参数复用、提前返回和延迟执行。
在一个函数中,首先填充几个参数,然后再返回一个新的函数的技术,称为函数的柯里化。通常可用于在不侵入函数的前提下,为函数 预置通用参数 ,供多次重复调用。
call 和 apply 都是为了解决改变 this 的指向。作用都是相同的,只是传参的方式不同。
除了第一个参数外, call 可以接收一个参数列表, apply 只接受一个参数数组。
bind 和其他两个方法作用也是一致的,只是该方法会返回一个函数。并且我们可以通过 bind 实现柯里化。
如何实现一个 bind 函数
对于实现以下几个函数,可以从几个方面思考
如何实现一个call函数
如何实现一个apply函数
箭头函数其实是没有 this 的,这个函数中的 this 只取决于他外面的第一个不是箭头函数的函数的 this 。在这个例子中,因为调用 a 符合前面代码中的第一个情况,所以 this 是 window 。并且 this 一旦绑定了上下文,就不会被任何代码改变。
关于 let 的是否存在变量提升,我们何以用下面的例子来验证:
let 变量如果不存在变量提升, console.log(name) 就会输出 ConardLi ,结果却抛出了 ReferenceError ,那么这很好的说明了, let 也存在变量提升,但是它存在一个“暂时死区”,在变量未初始化或赋值前不允许访问。
变量的赋值可以分为三个阶段:
关于 let 、 var 和 function :
依次输出:undefined -》 10 -》 20
答案: D
colorChange 方法是静态的。静态方法仅在创建它们的构造函数中存在,并且不能传递给任何子级。由于 freddie 是一个子级对象,函数不会传递,所以在 freddie 实例上不存在 freddie 方法:抛出 TypeError 。
1.使用第一次push,obj对象的push方法设置 obj 获取为 undefined
undefined {n:2}
首先,a和b同时引用了{n:2}对象,接着执行到a.x = a = {n:2}语句,尽管赋值是从右到左的没错,但是.的优先级比=要高,所以这里首先执行a.x,相当于为a(或者b)所指向的{n:1}对象新增了一个属性x,即此时对象将变为{n:1;x:undefined}。之后按正常情况,从右到左进行赋值,此时执行a ={n:2}的时候,a的引用改变,指向了新对象{n:2},而b依然指向的是旧对象。之后执行a.x = {n:2}的时候,并不会重新解析一遍a,而是沿用最初解析a.x时候的a,也即旧对象,故此时旧对象的x的值为{n:2},旧对象为 {n:1;x:{n:2}},它被b引用着。后面输出a.x的时候,又要解析a了,此时的a是指向新对象的a,而这个新对象是没有x属性的,故访问时输出undefined;而访问b.x的时候,将输出旧对象的x的值,即{n:2}。
在比较相等性,原始类型通过它们的值进行比较,而对象通过它们的引用进行比较。 JavaScript 检查对象是否具有对内存中相同位置的引用。
我们作为参数传递的对象和我们用于检查相等性的对象在内存中位于不同位置,所以它们的引用是不同的。
这就是为什么 { age: 18 } === { age: 18 } 和 { age: 18 } == { age: 18 } 返回 false 的原因。
所有对象键(不包括 Symbols )都会被存储为字符串,即使你没有给定字符串类型的键。这就是为什么 obj.hasOwnProperty(’1’) 也返回 true 。
上面的说法不适用于 Set 。在我们的 Set 中没有 “1” : set.has(’1’) 返回 false 。它有数字类型 1 , set.has(1) 返回 true 。
这题考察的是对象的键名的转换。
catch 块接收参数 x 。当我们传递参数时,这与变量的 x 不同。这个变量 x 是属于 catch 作用域的。
之后,我们将这个块级作用域的变量设置为 1 ,并设置变量 y 的值。现在,我们打印块级作用域的变量 x ,它等于 1 。
在 catch 块之外, x 仍然是 undefined ,而 y 是 2 。当我们想在 catch 块之外的 console.log(x) 时,它返回 undefined ,而 y 返回 2 。
常见React面试题
key值的作用是给同级的元素添加一个唯一标识,因为在React diff算法中,是根据key值来判断元素是否是新增还是移动等等,减少了不必要的元素重渲染。React 还需要借助 Key 值来判断元素与本地状态的关联关系。
shouldComponentUpdate 方法是用来判断render是否需要重新渲染DOM的,因为描绘DOM是非常耗性能的,所以能在这里生命周期里面写出优化的diff算法,就可以极大的提升性能。
虚拟DOM相当于是在js和真实DOM之中增加了一个缓存,利用dom diff算法避免了一些没有必要的dom操作,从而提升性能。
用JavaScript来表示一颗DOM树的话,相当于在第一次创建的时候,就创建好了一棵DOM数,当你状态发生改变时,会重新构造一棵虚拟DOM树来跟已经渲染好的真实DOM树进行对比,得出差异后再把记录的差异应用到真实的DOM树中,这样视图就更新了,也提高了性能。
4.1 把树形结构按照层级来分,进行同级之间的比较。
4.2 给列表中的每个单元赋予一个key值,方便比较。
4.3 react只会匹配相同组件名字的component
4.4 合并操作,调用component的setState方法,react将其标记一下dirty,到所有的事件循环结束之
后,就会检查所有react所标记过的dirty的component,然后重新渲染。
4.5 选择性子树渲染,开发人员可以重写shouldComponentUpdate提高
refs是React给我们提供的安全访问DOM元素或实例的方法,可以直接操控元素上有ref属性的DOM,方便开发。
类组件允许你使用更多的功能,例如钩子函数,自身的状态,也能直接访问store仓库并维持状态。
如果组件仅仅接收props,并且将组件自身渲染到页面上时,该组件就是一个无状态组件,可以使用一个纯函数来创建这样的组件。
state是一种数据结构,用于页面渲染时所使用的默认值,也是用户事件行为的结果。
props则是组件的配置,props由父传递给子组件,组件不能改变自身的props,但是可以把他的子组件的porps统一管理,props也可以传递回调函数。
受控组件有两个特点:
1.设置value值时,value由state控制。
2.value值一般在onchange事件中通过setState方法进行修改。
什么时候使用受控组件?
需要对组件的value值进行修改时,使用受控组件。比如:页面中有一个按钮,每点击一次按钮受控组件的值加1.
非受控组件有两个特点:
《input type=“text“ placeholder=“请输入姓名“ name=’username’ ref={(input) =》 this.usernameElem = input}/》
取值方法:this.usernameElem.value
什么时候使用非受控组件?
任何时候都不需要改变组件的value值,这时候可以使用非受控组件。
高阶组件其实就是一个高阶函数。高阶函数的定义是接受函数作为参数的函数。如果曾经使用过类似 map 这样的函数,可能已经很熟悉高阶函数。如果不熟悉 map ,它是一个数组遍历的方法,接受一个函数作为参数应用到数组中的每个元素。例如,可以像这样对一个数组作平方:
在super()被调用之前,子类是不能使用this的,在ES2015中,子类必须在constructor中调用super(),传递props给super()的原因是便于(在子类中)能在constructor访问this.props
应该在componentDidMount中发起网络请求。因为这个钩子函数会在DOM生成之后执行,在组件的生命周期中仅会执行一次。更重要的是,你不能保证在组件挂载之前Ajax请求完成,如果这样,你就意味着将一个未挂载的组件上调用setState方法,这将无效,所以在componentDidMount中发送请求可以保证组件可以更新。
为了解决跨浏览器兼容性问题,您的 React 中的事件处理程序将传递 SyntheticEvent 的实例,它是 React 的浏览器本机事件的跨浏览器包装器
都是用来构建React元素的。
React.createElement() 接收三个参数,第一个参数可以是标签名,第二个参数为传入的属性,第三个以及之后的参数为组件的子组件。
React.cloneElement()与 React.createElement()相似,不同的是他传入的第一个参数是React元素,而不是标签名或者组件。
React.createClass()、ES6 class 和无状态函数。
根据组件的职责通常把组件分为 UI 组件和容器组件。
UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。
两者通过 React-Redux 提供 connect 方法联系起来。
Flux的最大特点,就是数据的‘单向流动’。
用户访问view,view视图层发送用户的action,dispatch收到action之后,申请store进行更新,store更新后,发出一个‘change’事件,view收到‘change’事件之后事件发生改变。
1.creat-react-app
2.Yeoman
3.UmiJS
4.Beatle
5.DvaJS
redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer,工作流程是 view 调用 store 的 dispatch 接收 action 传入 store,reducer 进行 state 操作,view 通过 store 提供的 getState 获取最新的数据,flux 也是用来进行数据操作的,有四个组成部分 action,dispatch,view,store,工作流程是 view 发出一个 action,派发器接收 action,让 store 进行数据更新,更新完成以后 store 发出 change,view 接受 change 更新视图。Redux 和 Flux 很像。主要区别在于 Flux 有多个可以改变应用状态的 store,在 Flux 中 dispatcher 被用来传递数据到注册的回调事件,但是在 redux 中只能定义一个可更新状态的 store,redux 把 store 和 Dispatcher 合并,结构更加简单清晰
新增 state,对状态的管理更加明确,通过 redux,流程更加规范了,减少手动编码量,提高了编码效率,同时缺点时当数据更新时有时候组件不需要,但是也要重新绘制,有些影响效率。一般情况下,我们在构建多交互,多数据流的复杂项目应用时才会使用它们
一个组件所需要的数据,必须由父组件传过来,而不能像 flux 中直接从 store 取。
当一个组件相关数据更新时,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断。
提供两个对象(Connect,Provider),React-Redux 组件的作用是对 react 与 redux 进行连接,如果在 react 项目中直接使用 redux,那么需要把 redux 中的 store 数据,通过 props 属性,一层一层传递到组件中,这样做太麻烦了,所以可以借助 React-Redux 模块,可以跨层级的在任意组件中直接把 Redux 中的 store 数据取出来。
react面试题
Virtual DOM 是一个轻量级的 JavaScript 对象,它最初只是 real DOM 的副本。它是一个节点树,它将元素、它们的属性和内容作为对象及其属性。 React 的渲染函数从 React 组件中创建一个节点树。然后它响应数据模型中的变化来更新该树,该变化是由用户或系统完成的各种动作引起的。
Virtual DOM 工作过程有三个简单的步骤。
1、每当底层数据发生改变时,整个 UI 都将在 Virtual DOM 描述中重新渲染。
2、然后计算之前 DOM 表示与新表示的之间的差异。
3、完成计算后,将只用实际更改的内容更新 real DOM。
二、为什么浏览器无法读取JSX?
浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。
每个React组件强制要求必须有一个 render() 。它返回一个 React 元素,是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素,则必须将它们组合在一个封闭标记内,例如 《form》 、 《group》 、 《div》 等。此函数必须保持纯净,即必须每次调用时都返回相同的结果。
componentWillMount() – 在渲染之前执行,在客户端和服务器端都会执行。
componentDidMount() – 仅在第一次渲染后在客户端执行。
componentWillReceiveProps() – 当从父类接收到 props 并且在调用另一个渲染器之前调用。
shouldComponentUpdate() – 根据特定条件返回 true 或 false。如果你希望更新组件,请返回 true 否则返回 false 。默认情况下,它返回 false。
componentWillUpdate() – 在 DOM 中进行渲染之前调用。
componentDidUpdate() – 在渲染发生后立即调用。
componentWillUnmount() – 从 DOM 卸载组件后调用。用于清理内存空间。
Refs 是 React 中引用的简写。它是一个有助于存储对特定的 React 元素或组件的引用的属性,它将由组件渲染配置函数返回。用于对 render() 返回的特定元素或组件的引用。当需要进行 DOM 测量或向组件添加方法时,它们会派上用场。
React 会创建一个虚拟 DOM(virtual DOM)。当一个组件中的状态改变时,React 首先会通过 “diffing“ 算法来标记虚拟 DOM 中的改变,第二步是调节(reconciliation),会用 diff 的结果来更新 DOM。
高阶组件是重用组件逻辑的高级方法,是一种源于 React 的组件模式。 HOC 是自定义组件,在它之内包含另一个组件。它们可以接受子组件提供的任何动态,但不会修改或复制其输入组件中的任何行为。你可以认为 HOC 是“纯(Pure)”组件。
HOC可用于许多任务,例如:
Redux 使用 “Store” 将程序的整个状态存储在同一个地方。因此所有组件的状态都存储在 Store 中,并且它们从 Store 本身接收更新。单一状态树可以更容易地跟踪随时间的变化,并调试或检查程序。
因为 this.props 和 this.state 的更新可能是异步的,不能依赖它们的值去计算下一个 state。
React Native 面试题整理(含答案)
下边我们看看props.children可能的值有哪些:
1:undefined 2: string 3: object 4: array;
解决办法二:
第一种实现用例:
第二种实现方式用例:
详细参考: 用例: