React详解

前言

React是一个用于构建用户界面的javaScript库,起源于facebook的内部项目,在13年f进行开源

17版本官网:React – A JavaScript library for building user interfaces

18版本官网:React 官方中文文档

特点:

  1. 声明式编码,组件化编码能提高开发效率和组件复用性
  2. React Native 编写原生应用
  3. 高效(优秀的Diffing算法)

一、基础

主要核心,依赖下面四个文件
    <!-- 引入核心库。全局出现React对象--><script type="text/javascript" src="./React-js/16.8/react.development.js"></script><!-- 用于支持react操作DOM。全局出现ReactDOM对象--><script text="text/javascript" src="./React-js/16.8/react-dom.development.js"></script><!-- 用于将jsx转换为js --><script text="text/javascript" src="./React-js/16.8/babel.min.js"></script><!-- 用于对组件标签属性进行限制。全局出现PropTypes对象 --><script src="./React-js/16.8/prop-types.js"></script>

1、基本使用

1.1、虚拟dom

关于虚拟DOM:

  • 本质是object类型的对象(一般对象)
  • 虚拟DOM比较“轻”,真实DOM比较“重”,因为虚拟DOM是React内部在用,无需真实DOM 上:那么多的属性。
  • 虚拟DOM最终会被React转化为真实DOM。呈现在页面上
<body><div id="test"></div><!-- 引入核心库 --><script type="text/javascript" src="./React-js/16.8/react.development.js"></script><!-- 用于支持react操作DOM --><script text="text/javascript" src="./React-js/16.8/react-dom.development.js"></script><!-- 用于将jsx转换为js --><script text="text/javascript" src="./React-js/16.8/babel.min.js"></script><!-- 一定是babel --><script type="text/babel">// 创建虚拟domconst VDOM = <h1>Hello.React</h1>const VDOM2 = <h1>----------------</h1>// 渲染虚拟DOM到页面(后面的会替换之前)ReactDOM.render(VDOM,document.getElementById('test'))ReactDOM.render(VDOM2,document.getElementById('test'))</script>
</body>

 2.2、JSX的语法规则

1、全称:  JavaScript XML。

2、react定义的一种类似于XMLJS扩展语法: JS + XML本质是React.createElement(componentprops, ...children)方法的语法糖

3、作用: 用来简化创建虚拟DOM

     写法:var ele = <h1>Hello JSX!</h1>

     注意1:它不是字符串, 也不是HTML/XML标签

     注意2:它最终产生的就是一个JS对象

  • 定义虚拟DOM时,不要写引号。
  • 标签中混入JS表达式时要用{}-
  • 样式的类名指定不要用class,要用className.
  • 内联样式,要用style={{key : value}}的形式去写。
  • 只有一个根标签
  • 标签必须闭合
  • 标签首字母
  • (1).若小写字母开头,则将改标签转为htm1中同名元素,若htm1中无该标签对应的同名元素,则报错。
  • (2).若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。
<body><div id="test"></div><!-- 引入核心库 --><script type="text/javascript" src="./React-js/16.8/react.development.js"></script><!-- 用于支持react操作DOM --><script text="text/javascript" src="./React-js/16.8/react-dom.development.js"></script><!-- 用于将jsx转换为js --><script text="text/javascript" src="./React-js/16.8/babel.min.js"></script><!-- js写法 --><script type="text/javascript">// 创建虚拟domconst VDOM = React.createElement('h1',{id:'title'},React.createElement('span',{},'js写法'))// 渲染虚拟DOM到页面(后面的会替换之前)ReactDOM.render(VDOM, document.getElementById('test'))</script><!-- jsx写法 --><script type="text/babel">const data = ['抽烟','喝酒','烫头']const obj = {name1:'抽烟',name2:'喝酒',name3:'烫头'}const myId = 'song'const myData = 'HELLO'const VDOM = (<div><h1 className="box" id={myId}><span style={{ color: 'red', fontSize: '40px' }}>{myData.toLocaleLowerCase()}</span></h1><input type="text" /><ul>{// data   // 直接使用数组,会自动遍历// obj     // 对象,会报错data.map((item,i)=><li key={i}>{item}</li>)}</ul></div>)// 渲染虚拟DOM到页面(后面的会替换之前)ReactDOM.render(VDOM, document.getElementById('test'))</script>
</body>

2、函数式组件

 <script type="text/babel">// 定义函数组件function Demo() {console.log(this);  // 经过babel转化开启严格模式,this没有明确的调用,所以为undefinedreturn <h2>函数定义的组件</h2>}// 渲染组件到页面ReactDOM.render(<Demo />, document.getElementById('test'))/*执行了ReactDOM.render( <MyComponent/>.......之后,发生了什么?1.React解析组件标签,找到了MyComponent组件。2.发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOW转为真实DOM,随后呈现在页面中。*/</script>

3、类组件

<script type="text/babel">// 定义类组件class Demo extends React.Component{render(){// render:类的原型对象上(可在浏览器控制台输入Demo回车测试),供实例使用// this指向Demo的实例对象。俗称:组件对象或组件实例对象console.log('render中this',this);return (<h2>类定义的组件</h2>)}}// 渲染组件到页面ReactDOM.render(<Demo />, document.getElementById('test'))/*执行了ReactDOM.render( <MyComponent/>.......之后,发生了什么?1.React解析组件标签,找到了MyComponent组件。2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用原型上的render方法3.将返回的虚拟DOW转为真实DOM,随后呈现在页面中。*/</script>

3.1、constructor

<script type="text/babel">// 定义类组件class Weather extends React.Component {// 构造器是否接受props,是否传递super,取决于:是否需要在构造器中通过this访问props// 若是写了构造器,不给super传props则,在构造器中拿不到props。为undefinedconstructor(props) {    // 构造器只调用一次 // super(props)super()console.log(this.props);}render() {return (<h2 ></h2>)}}const p = { name: 'tom', age: 18, sex: '女' }// 渲染组件到页面ReactDOM.render(<Weather {...p} />, document.getElementById('test'))</script>

4、组件的三大核心

4.1、state:存放状态

 <script type="text/babel">// 定义类组件class Weather extends React.Component {constructor(props) {    // 构造器只调用一次 super(props)// 初始化状态this.state = {isHot: false,wind: '大风'}// 改变原型上的demo的this指向,并把原型上的demo赋值到实例上的demo上。处理下面this为undefindthis.demo = this.demo.bind(this)}render() {     // 调用1+n次。1:初始化   n:状态更新的次数return (<h2 onClick={this.demo}>今天天气{this.state.isHot ? '炎热' : '很冷'}</h2>)}demo() {// demo放在哪里? Weather的原型对象上,供实例使用//由于demo是作为onclick的回调,所以不是通过实例调用的,是直接调用//类中的方法默认开启了局部的严格模式,所以demo中的this为undefinedconsole.log('this', this); // undefind// 不能直接修改值。数据虽然变化,但页面不刷新// this.state.isHot = !this.state.isHot// 注意:需要通过setState方法来修改状态this.setState({ isHot: !this.state.isHot })}}// 渲染组件到页面ReactDOM.render(<Weather />, document.getElementById('test'))function demo() {// console.log('被点击');alert('被点击')}</script>
(1)、state简写
<script type="text/babel">// 定义类组件class Weather extends React.Component {// 初始化状态state = { isHot: false, wind: '大风' }render() {    return (<h2 onClick={this.demo}>今天天气{this.state.isHot ? '炎热' : '很冷'}</h2>)}// 自定义方法---需要赋值语句的形式+箭头函数demo = ()=> {console.log('this', this); // undefindthis.setState({ isHot: !this.state.isHot })}}// 渲染组件到页面ReactDOM.render(<Weather />, document.getElementById('test'))</script><!-- 1、组件中 render方法中的this 为组件实例对象-2、组件自定义的方法中this为 undefined,如何解决?a.强制绑定this:通过函数对象bindb.箭头函数3、状态数据,不能直接修改或更新-->

 4.2、props:接收参数

 <script type="text/babel">// 定义类组件class Weather extends React.Component {render() {console.log(this);return (<ul><li>姓名:{this.props.name}</li><li>性别:{this.props.sex}</li><li>年龄:{this.props.age}---{this.props.flag}</li></ul>)}}const p = { name: 'tom', age: 18, sex: '女' }// 渲染组件到页面ReactDOM.render(<Weather {...p} flag={666}/>, document.getElementById('test'))</script>
(1)、props限制

    <!-- 用于对组件标签属性进行限制。全局出现PropTypes对象 -->

    <script src="./React-js/16.8/prop-types.js"></script>

 <script type="text/babel">// 定义类组件class Weather extends React.Component {render() {console.log(this);// 注意:props是只读的this.props.speak()return (<ul><li>姓名:{this.props.name}</li><li>性别:{this.props.sex}</li><li>年龄:{this.props.age+1}-----</li></ul>)}}// propTypes:给类加规则Weather.propTypes = {// 在15以及以下版本// name:React.PropTypes.string// 16版本及以上,需要通过引入PropTypes对象name:PropTypes.string,sex:PropTypes.string,age:PropTypes.number.isRequired,  // isRequired。必传speak: PropTypes.func  // 限制为函数}// 设置不传时的默认值Weather.defaultProps = {sex:'我是默认值'}// 渲染组件到页面ReactDOM.render(<Weather name="song" age={666} speak={fun}/>, document.getElementById('test'))function fun (){console.log('我是函数');}</script>
(2)、简写
<script type="text/babel">class Weather extends React.Component {// 写在类里面,相当于给类加属性static propTypes = {name: PropTypes.string,sex: PropTypes.string,age: PropTypes.number.isRequired,  // isRequired。必传speak: PropTypes.func  // 限制为函数}static defaultProps = {sex: '我是默认值'}render() {console.log(this);// 注意:props是只读的this.props.speak()return (<ul><li>姓名:{this.props.name}</li><li>性别:{this.props.sex}</li><li>年龄:{this.props.age + 1}-----</li></ul>)}}// 渲染组件到页面ReactDOM.render(<Weather name="song" age={666} speak={fun} />, document.getElementById('test'))function fun() {console.log('我是函数');}</script>
(3)、在函数组件的使用
// 定义函数组件function Weather(props) {console.log(this, props);  // 经过babel转化开启严格模式,this没有明确的调用,所以为undefinedreturn (<ul><li>姓名:{props.name}</li><li>性别:{props.sex}</li><li>年龄:{props.age + 1}-----</li></ul>)}Weather.propTypes = {name: PropTypes.string,sex: PropTypes.string,age: PropTypes.number.isRequired,}Weather.defaultProps = {sex: '我是默认值'}// 渲染组件到页面ReactDOM.render(<Weather name="song" age={666} />, document.getElementById('test'))

 4.3、refs与事件处理

(1)、字符串形式的ref
        class Demo extends React.Component{// 展示左侧输入框的数据showData = ()=>{alert(this.refs.inp1.value)}// 展示左侧输入框的数据showData2 = ()=>{alert(this.refs.inp2.value)}render(){return(<div><input ref="inp1" type="text" placeholder="点击按钮提示数据"/><button onClick={this.showData}>点击提示左侧的数据</button>&nbsp;<input ref="inp2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/></div>)}}
(2)、回调函数形式的ref
        class Demo extends React.Component {state = { isHot: true }// 展示左侧输入框的数据showData = () => {alert(this.inp1.value)}changWeacter = () => this.setState({ isHot: !this.state.isHot })/*** ref若是以下面内联函数的方式定义,它在更新过程中会别执行两次,* 第一次传入参数为null,第二次才是DOM元素* 因为每次渲染时都会创建新的函数实例,所以React清空旧的ref,被设置新的、* ** 不过可以把回调函数定义成class的绑定函数的方式可以避免,* */saveInp = (c)=>{this.inp2 = c; console.log('绑定函数@', c)}render() {const { isHot } = this.state// return (<div><h1>今天天气{this.state.isHot ? '炎热' : '很冷'}</h1>{/* c:input标签。相当于往Demo身上添加了inp1属性,把input标签赋值给它。内联函数方式*/}<input ref={c => { this.inp1 = c; console.log('@', c) }} type="text" placeholder="点击按钮提示数据" />{/* 使用class绑定函数的方式 */}<input ref={this.saveInp} type="text" placeholder="点击按钮提示数据" /><button onClick={this.showData}>点击提示左侧的数据</button>&nbsp;<button onClick={this.changWeacter}>点击切换天气</button></div>)}}
(3)、API形式的ref
class Demo extends React.Component {/** React.createRef* 存放被ref标识的节点,但只能单独存一个*/ myRef = React.createRef()myRef2 = React.createRef()// 展示左侧输入框的数据showData = () => {console.log(this.myRef,this.myRef2);}render() {// return (<div><input ref={this.myRef} type="text" placeholder="点击按钮提示数据" /><input ref={this.myRef2} type="text" placeholder="点击按钮提示数据" /><button onClick={this.showData}>点击提示左侧的数据</button>&nbsp;</div>)}}

5、事件处理

class Demo extends React.Component {/** * 1、通过onXxx属性指定事件处理函数(注意大小写)* (1)React使用的是自定义(合成)事件, 而不是使用的原生DOM事件  ---为了处理兼容* (2)React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)    --- 为了高效* 2、通过event.target得到发生事件的DOM元素对象*/myRef = React.createRef()myRef2 = React.createRef()// 展示左侧输入框的数据showData = () => {console.log(this.myRef, this.myRef2);}showData2 = (e) => {console.log(e.target.value);}render() {// return (<div><input ref={this.myRef} type="text" placeholder="点击按钮提示数据" /><button onClick={this.showData}>点击提示左侧的数据</button>&nbsp;<input onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" /></div>)}}

5.1、函数柯里化与高阶函数

/** * *高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。* 1.若A雨数,接收的参数是一个函数,那么A就可以称之为高阶函数。* 2.若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。*   常见的高阶函数有: Promise、setTimeout、arr.map()等等* * *函数的柯里化: 通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式。*/// 普通写法
function sum(a,b,c){return a+b+c
}
const res = sum(1,2,3)// 柯里化写法
function sum(a){return (b)=>{return (c)=>{return a+b+c}}
}
const res = sum(1)(2)(3)
        /* 普通写法: */class Demo extends React.Component {state = {username:'',password:''}// 保存saveUsername = (e)=>{this.setState({username:e.target.value})}savePassword = (e)=>{this.setState({password:e.target.value})}// 展示左侧输入框的数据handleSubmit = (e)=>{e.preventDefault()  // 阻止默认行为const {username,password } = this.stateconsole.log('用户名密码:',username,password);}render() {// return (<form onSubmit={this.handleSubmit}>用户名:<input onChange={this.saveUsername} type="text" />密码:<input onChange={this.savePassword} type="password" /><button>登录</button></form>)}}/* 柯里化写法: */class Demo extends React.Component {state = {username: '',password: ''}// 保存。柯里化写法saveData = (dataType) => {console.log('dataType', dataType);return (e) => {this.setState({ [dataType]: e.target.value })}}handleSubmit = (e) => {e.preventDefault()  // 阻止默认行为const { username, password } = this.stateconsole.log('用户名密码:', username, password);}render() {// return (<form onSubmit={this.handleSubmit}>用户名:<input onChange={this.saveData('username')} type="text" />密码:<input onChange={this.saveData('password')} type="password" /><button>登录</button></form>)}}/* 不使用柯里化写法: */class Demo extends React.Component {state = {username: '',password: ''}// 保存。saveData = (dataType, data) => {console.log('dataType', dataType, data);this.setState({ [dataType]: data })}handleSubmit = (e) => {e.preventDefault()  // 阻止默认行为const { username, password } = this.stateconsole.log('用户名密码:', username, password);}render() {return (<form onSubmit={this.handleSubmit}>用户名:<input onChange={(e) => this.saveData('username', e.target.value)} type="text" />密码:<input onChange={(e) => this.saveData('password', e.target.value)} type="password" /><button>登录</button></form>)}}

6、生命周期

6.1、旧版

 1. 初始化阶段: 由ReactDOM.render()触发---初次渲染

            1.constructor()

            2.componentWillMount()

            3.render()

            4.componentDidMount()

 2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发

            1.shouldComponentUpdate()

            2.componentWillUpdate()

            3.render()

            4.componentDidUpdate()

3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发

            1.componentWillUnmount()

(1)、案例

6.2、新版

1. 初始化阶段: ReactDOM.render()触发---初次渲染

  1. constructor()
  2. getDerivedStateFromProps
  3. render()
  4. componentDidMount()

2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发

  1. getDerivedStateFromProps
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate
  5. componentDidUpdate()

3. 卸载组件: ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount()

未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/251079.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目中使用sonar扫码代码

1.在maven的settings.xml配置 org.sonarsource.scanner.maven <profiles> <profile><id>sonar</id><activation><activeByDefault>true</activeByDefault></activation><properties><!-- Optional URL to server. D…

ubuntu20配置mysql8

首先更新软件包索引运行 sudo apt update命令。然后运行 sudo apt install mysql-server安装MySQL服务器。 安装完成后&#xff0c;MySQL服务将作为systemd服务自动启动。你可以运行 sudo systemctl status mysql命令验证MySQL服务器是否正在运行。 连接MySQL 当MySQL安装…

MySQL进阶45讲【10】MySQL为什么有时候会选错索引?

1 前言 前面我们介绍过索引&#xff0c;在MySQL中一张表其实是可以支持多个索引的。但是&#xff0c;写SQL语句的时候&#xff0c;并没有主动指定使用哪个索引。也就是说&#xff0c;使用哪个索引是由MySQL来确定的。 大家有没有碰到过这种情况&#xff0c;一条本来可以执行得…

【服务器】RAID(独立磁盘冗余阵列)

RAID&#xff08;独立磁盘冗余阵列&#xff09; 一、RAID的介绍二、RAID的分类#2-1 RAID 02-2 RAID 1#2-3 RAID 32-4 RAID 52-5 RAID 62-6 RAID 10(先做镜像&#xff0c;再做条带化)2-7 RAID 01&#xff08;先做条带&#xff0c;再做镜像&#xff09;2-8 RAID比较 三、磁盘阵列…

FANUC机器人示教器的菜单变成了图标,如何改成列表的形式?

FANUC机器人示教器的菜单变成了图标&#xff0c;如何改成列表的形式&#xff1f; 如下图所示&#xff0c;开机后按下MENU菜单键时&#xff0c;发现原来的列表形式变成了菜单图标的形式&#xff0c;同时在按F1-F5键时&#xff0c;提示&#xff1a;HMI模式-键不可用&#xff0c; …

蓝桥杯备战——12.超声波与测频代码优化

1.优化分析 昨天我在看原理图的发现超声波模块的反馈引脚P11刚好可以使用PCA模块0的捕获功能&#xff0c;我就想着把PCA功能留给超声波&#xff0c;然后测频功能还是改成定时器0来完成&#xff0c;然后前后台功能改成定时器1。 至于我为什么要这么改呢&#xff0c;看一下我原…

uniapp 高德地图显示

1. uniapp 高德地图显示 使用前需到**高德开放平台&#xff08;https://lbs.amap.com/&#xff09;**创建应用并申请Key   登录 高德开放平台&#xff0c;进入“控制台”&#xff0c;如果没有注册账号请先根据页面提示注册账号   打开 “应用管理” -> “我的应用”页面…

【Mysql】整理

Mysql整理与总结 整理Mysql的基本内容供回顾。 参考&#xff1a; [1]. 掘金.MySQL三大日志(binlog,redolog,undolog)详解 [2]. Javaguide.MySQL三大日志(binlog、redo log和undo log)详解

陶哲轩如何用 GPT-4 辅助数学研究

关于陶哲轩&#xff08;Terence Tao&#xff09;用 GPT-4 进行数学研究的话题始于陶本人在 微软 Unlocked 上发表的 Embracing Change and Resetting Expectations 一文。文中提到&#xff1a; …… I could feed GPT-4 the first few PDF pages of a recent math preprint and…

Zookeeper服务注册与发现实战

目录 设计思路 Zookeeper注册中心的优缺点 SpringCloudZookeeper实现微服务注册中心 第一步&#xff1a;在父pom文件中指定Spring Cloud版本 第二步&#xff1a;微服务pom文件中引入Spring Cloud Zookeeper注册中心依赖 第三步&#xff1a; 微服务配置文件application.y…

47 mmap 的实现

前言 mmap 函数经常是和 普通的 bio 进行一个参照对比 mmap 相比于 bio 减少了一次 系统空间 到 用户空间 的拷贝操作 普通的 bio 的流程可以参见这里 从磁盘读取数据到内存的调试 这里 我们来看一下 mmap 测试用例 测试用例如下, 仅仅是一个 mmap 的一个简单的使用 …

k8s之安装部署及kuboard发布应用

目录 环境准备 系统规划 配置免密 将桥接的IPv4流量传递到iptables的链 系统基础配置 安装docker 安装docker及基础依赖 配置docker的仓库下载地址 部署k8s 添加阿里云的k8s源 安装kubeadm&#xff0c;kubelet和kubectl 初始化masteer节点 部署node节点 部署flanne…

Java设计模式 – 四大类型

设计模式 – 四大类型 创建型模式结构型模式行为型模式J2EE模式 设计模式&#xff08;Design pattern&#xff09;是重构解决方案 根据书Design Patterns – Elements of Reusable Object-Oriented Software&#xff08;中文译名&#xff1a;设计模式 – 可复用的面向对象软件元…

2024美赛数学建模E题思路源码

赛题目的 可以将其拆解为以下主要问题&#xff0c;并为每个问题提出解决方案&#xff1a; 如何在极端天气事件越来越多的地区部署财产保险&#xff1f;保险公司应在何时何地承保保单&#xff1f;业主如何影响保险公司的承保决定&#xff1f;如何建立能够评估未来房地产决策的…

在windows和Linux中的安装 boost 以及 安装 muduo 和 mysql

一、CMake安装 Ubuntu Linux 下安装和卸载cmake 3.28.2版本-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/135960115?spm1001.2014.3001.5501二、安装boost boost官网&#xff1a;boost官网 我下载的boost版本&#xff1a; windows:boost_1_84_0.zipli…

如何计算两个指定日期相差几年几月几日

一、题目要求 假定给出两个日期&#xff0c;让你计算两个日期之间相差多少年&#xff0c;多少月&#xff0c;多少天&#xff0c;应该如何操作呢&#xff1f; 本文提供网页、ChatGPT法、VBA法和Python法等四种不同的解法。 二、解决办法 1. 网页计算法 这种方法是利用网站给…

vscode debug无法直接查看eigen变量的问题(解决方法)

主要是给gdb添加一个Eigen相关的printer即可, 网上其他教程都搞太复杂了, 我整理成了一个仓库, 把仓库克隆下来直接运行 ./setup.sh脚本即可配置好 git clone gitgithub.com:fandesfyf/EigenGdb.git cd EigenGdb ./setup.sh 然后在vscode中重新debug即可。 效果 …

修改MFC图标

摘要&#xff1a;本文主要讲解了MFC程序窗口图标的添加、任务栏、底部托盘的图标添加&#xff0c;以及所生成的exe文件图标的添加。 ​​​​​​​1、在资源视图添加Icon资源 透明图标怎么制作&#xff1f; 1&#xff09;点击图片》右键&#xff1a;使用画图3D进行编辑 2&a…

[C++]:15.继承

继承 一.继承&#xff1a;1.继承的概念和基本操作&#xff1a;1.概念&#xff1a;2.基本操作&#xff1a; 2.继承格式和多种继承方法&#xff1a;1.基本继承格式&#xff1a;2.继承关系访问限定符 3.子类对象和父类对象之间的赋值&#xff1a;1.为什么存在赋值兼容转换&#xf…

如果通过浏览器调试?

背景&#xff1a;博主是一个有丰富经验的后端开发人员&#xff0c;在前端开发中感觉总是有种力不从心的感觉&#xff0c;因为没有后端debug调试的清晰感。 解决办法&#xff1a;掌握chorm浏览器调试技巧。 F12&#xff0c; F5 打上断点之后&#xff0c;这不就是梦寐之中的调试…