简介
web 开发其实是 html/js/css。前端开发们使用 javascript 脚本语言,调用 html 标准的 domapi 渲染dom标签,使用 js 逻辑处理按钮交互逻辑
随着开发的业务越来越复杂,代码量越来越大,原始的 html / js / css 写出的代码复用困难,可读性低。于是聪明的程序员用新的开发思想编写了 React 框架
本文介绍了一些知识点帮助非前端的小伙伴们学习react,快速建立起知识体系
文档建议
比较官方的文档推荐
js api 索引:https://developer.mozilla.org/zh-CN/
react: https://react.docschina.org/tutorial/tutorial.html
开发环境搭建
现在 web 开发会用到一些打包框架,来创建项目,语法转换,压缩代码,这些打包框架需要使用 nodejs 环境。包括 rn 也是需要 node 12+ 的环境。
nvm
推荐使用 nvm,而不是安装 nodejs
nvm 是一个 nodejs 版本管理工具,当你需要切换 nodejs 版本时,nvm 是一个很好的工具
windows 安装nvm :https://www.jianshu.com/p/96f9317db0b5
mac 安装nvm:https://www.jianshu.com/p/622ad36ee020
mac 注意安装最新版本 nvm,并且 mac m1 芯片 需要使用兼容模式安装
当终端 nvm 命令可以执行,且 node -v 正确显示 nodejs 版本 就算安装成功
然后使用 nvm install 安装nodejs
使用nvm list 查看已安装版本
使用nvm use <virsion> 使用对应版本nodejs
vscode
html js css 学习
js
- 变量声明
var name = '张三'
var age = 18
console.log(name)
console.log(age)
- 类型/类型判断
基础类型:string number boolean null undefined symbol
null 会被typeof
判断为 object 但他与引用类型是有区别的
// 字符串
var name = '张三'
console.log(typeof name) // string
// 数字
var age = 18
console.log(typeof age) // number
// 布尔
var isMan = true
console.log(typeof isMan) // boolean
// 空对象
var girlfriend = null
console.log(typeof girlfriend) // null
// 未定义
var baby
console.log(typeof baby) // object
// 唯一值
var id = Symbol('张三')
console.log(typeof id) // symbol
引用类型:object function array 等
// 对象
var person = {
name: '张三',
age: 18,
isMan: true,
girlfriend: null
}
// 对象取值 .
console.log(person.name)
// 对象取值 []
console.log(person['name'])
// 数组 成员可以是任意类型,甚至可以是函数
var array = ['张三',18,true,null,function(){}]
// 数组取值 [] 下标从0开始
console.log(array[0])
从内存来看,基础类型的变量对应着实际的值,而引用类型的变量对应着存储着这些基础类型值的地址,这意味着当你使用=把一个引用类型的值赋给变量时,存储的实际上是地址,并没有生成一个新的对象,而当你使用key访问并修改新变量上的值时,老变量也会受到影响。这时我们就需要深拷贝去创建一个新的对象
var obj1 = {
name: '鲤鱼王',
level: 19
}
var obj2 = obj1
obj2.level++
obj2.name = '暴鲤龙'
console.log(obj1, obj2)
- 深拷贝/浅拷贝
上面说的,自己百度吧 - 函数
实现功能的代码块
funtion 和 箭头函数
function add(num1, num2){
return num1 + num2
}
console.log(add(1,2)) // 3
const addLambda = (num1, num2) => num1 + num2
console.log(addLambda(1,2)) // 3
- if / switch
条件分支
var person = {
name: '张三',
age: 18,
isMan: true,
girlfriend: null
}
// if判断
if(person.isMan === true){
console.log('进入男厕所')
}else{
console.log('进入女厕所')
}
// switch
switch(person.isMan){
case true: console.log('进入男厕所');break;
case false: console.log('进入女厕所');break;
default: console.log('mei sha yi yi ');break
}
- 循环
for 和 while
这个应该不用讲 - 垃圾回收与闭包
除非你知道闭包是怎么回事,不然躲着点写
js的垃圾回收机制简单来说就是在变量无论如何也访问不到时,js会将这个变量回收
例如
// 例如一个函数执行结束之后
function fn(){
var a = 1
}
fn()
// 例如失去引用
var a = {
name:'a'
}
// 这里的‘a’失去了引用
a.name=1
不过,一旦A函数返回另一个B函数,在B函数中又引用了A函数作用域中的变量,那么就算A函数运行完这个B函数也会一直引用A函数作用域中的变量,造成不回收,形成闭包。可以利用这一特性存储一些数据
function A{
var name='A'
return function B(){
console.log(name)
}
}
// 这里就形成了一个闭包
const fnB=A()
- 类 与 原型 面向对象
虽然支持 class 语法,但 js 中是的类是用原型链实现的,不建议初学去了解,语法介绍一下
// 单位
class Item {
// 名称
name = ''
// 位置
pos={
x:0,
y:0
}
constructor(name){
this.name = name
}
// 移动
moveTo(x,y){
this.pos.x=x
this.pos.y=y
console.log(`${this.name}移动到了x=${this.pos.x},y=${this.pos.y}`)
}
}
// 宝可梦
class Pokemon extends Item {
// 技能
skills = []
// 放技能
useSkill(index){
console.log(this.name+'!,快使用'+this.skills[index])
}
// 学习技能
learnSkill(skillName){
this.skills.push(skillName)
}
}
const pikachu = new Pokemon('皮卡丘')
pikachu.moveTo(25,30)
pikachu.learnSkill('十万伏特!!')
pikachu.learnSkill('快躲开!!')
pikachu.useSkill(1)
这样我们就创建好了 Item 类 作为地图上的物体,以及 Pokemon 类 去做宝可梦的动作
- 常用调试api
// 等级info
console.log('你好')
// 等级warning
console.warn('你好')
// 等级error
console.error('你好')
// 浏览器断点
debugger;
- 隐式转换
有趣的jacascript
比如 + - 这些运算符,会对变量进行隐式转换
常见number+string的转换是调用对象的toString方法
或者-的把变量强制转换number类型
console.log(1+'1') // '11'
console.log(1-'1') // 0
console.log(1-[]) // 1
console.log(1+[]) // '1'
console.log(1+{}) // '1[object Object]'
- 变量提升和作用域
了解就行
var 和 funcion 的变量会提升至作用域顶端
而 const let 和 箭头函数 不会
// var 提升
console.log(a) // undefined
var a = 1
console.log(a) // 1
// function 提升
fn1()
function fn1(){
console.log(1)
}
fn2() // 代码执行到这里就会报错 fn2 is not defined
const fn2 = () => console.log(2)
- ajax 请求
我们用封装好的axios库,并不需要自己手写ajax请求,了解就好
原生请求有 XMLHttpRequest 和 fetch 可以去 mdn 查 - es6 常用api
博客:https://es6.ruanyifeng.com/
文档:https://developer.mozilla.org/zh-CN/ - 异步 宏任务微任务 和事件循环
这也不用学,了解就好
js容器是v8引擎,v8引擎是单线程,当他遇到开销较大的代码是就会卡住,导致后续支持渲染的函数滞后运行,所以js提供了一个事件循环实现异步
常见的异步函数有定时器 setTimeout/setInterval,promise,ajax
异步任务会在主线程空闲时通过事件循环被调用
其中 setTimeout/setInterval 是宏任务,放进宏任务队列
其中 promise 是微任务 放进微任务队列
微任务的优先级比宏任务高
常用Promise.resolve().then()
创建一个微任务
也可以通过queueMicrotask
创建一个微任务
setTimeout(()=>console.log(1),0)
Promise.resolve().then(()=>console.log(2))
console.log(3)
// 3会比12先输出,因为12是异步任务
// 2会比1先输出,因为Promise创建的是微任务
- Promise
Promise的功能
- 封装了一组状态 pedding/fulfilled/rejected
- 内部状态,只有创建promise时传入的function的resolve和reject可以修改
- 状态一旦修改就锁定了
- 可以通过.then .catch 函数执行不同状态的回调
通常我们用promise是一个未知异步结果,对他的成功/失败状态执行不同的function
ajax 是最常见的异步
// img 的 onload 和 onerror 为例
function reqSrc(img){
return new Promise((resolve,reject)=>{
img.src='http://heihei.com/pics/wuwuwu.jpg'
img.onload=resolve
img.onerror=reject
})
}
const imgReqSreResult=reqSrc(img)
imgReqSreResult.then(()=>{
console.log('成功了')
}).catch(()=>{
console.log('失败了')
})
- async/await
async/await 原理是生成器函数的语法糖,生成器函数可以在下一次迭代前停止执行
async声明的是一个异步函数,他将返回一个Promise,在async函数中使用await 修饰的异步函数,会在其执行结束之前阻塞后续代码执行(虽然说阻塞,但实际上还是被事件循环调用,不会影响主线程)
async function InitImg(){
function reqSrc(img){
return new Promise((resolve,reject)=>{
img.src='http://heihei.com/pics/wuwuwu.jpg'
img.onload=resolve
img.onerror=reject
})
}
const imgReqSreResult = await reqSrc(img)
console.log(1) // 虽然 reqSrc是个异步任务,log函数还是会在其执行后打印,因为这是在async函数中 reqSrc这个promise被await了
}
- try/catch
异常捕获
var obj={
skillList:['十万伏特']
}
try{
console.log(obj.skillList[1])
}catch(e){
console.log(e)
}
- 模块化
2种风格 commonjs 和 esmodule
commonjs 通常用在 nodejs 他的语法
// main.js
const moduleA = require('./a.js')
...
// a.js
module.exports={
name:'moduleA'
}
esmodule 用在浏览器
// main.js
import moduleA from './a.js'
...
// a.js
export default {
name:'moduleA'
}
html - 并不重要,百度看文档就行
- 标签
- dom api
css - 看文档就行
- 样式表
- flex 布局
移动端常用布局
博客:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html