ES6
含义
- ES6就是ECMAScript 6,它是JavaScript语言的一套标准。
参考网站
变量声明
- var 是js 原生关键字,它和function都会变量提升。
- let 是ES6提供的关键字,不会变量提升。
- const 一般用作声明常量,一旦声明,不可更改,而且常量必须初始化赋值,不会变量提升。但如果定义的是对象Object,那么修改对象内部的属性值和增删键值对也是可以的。
- 隐式声明的变量具有全局作用范围,而无论是否位于函数内。
- 变量在一个块作用域内被 var、let、const中的一个声明过后,便不能再被另外两个关键字声明了
变量提升
- 代码输入顺序
function foo() {
console.log(a);
var a = 1;
console.log(a);
function a() {}
console.log(a);
}
foo();
- 实际执行顺序
function foo() {
var a;
function a() {}
console.log(a); // a()
a = 1;
console.log(a); // 1
console.log(a); // 1
}
foo();
箭头函数
// 函数表达式
let x = function(x, y) {
return x * y;
}
等价于
// 使用箭头函数的函数表达式
let x = (x, y) => x * y;
// 遍历元素
for(i of s1){
console.log(i);
}
默认参数值
function sum(x, y = 5) {
console.log(x + y);
}
sum(5);//10
sum(5, 15);//20
模板字符串
- var、let、const、隐式声明变量都可以使用。
const first_name = "Jack";
const last_name = "Sparrow";
console.log('Hello ' + first_name + ' ' + last_name);
可改为
const first_name = "Jack";
const last_name = "Sparrow";
console.log(`Hello ${first_name} ${last_name}`);
创建、实例化、访问一个类
class Person {
constructor(name) {
this.name = name;
}
}
const person1 = new Person('John');
console.log(person1.name);//John
- 对象访问
解构
- 数组解构,可以使用 const、let、var 和隐式声明来接受解构结果。
- 对象解构要用 const 或 let 声明解构结果。
- 解构时要保证与主键名称保持一致
导入导出
- 分为命名式导入导出(名称导入导出)和默认导入导出(定义式导入导出)。
- 命名式导出每个模块可以多个,默认导出每个模块仅一个。
命名式导出导出
// 导出 export.js
export const a = 1;
const b = 2;
export {b as bb};
export let c = ()=>{};
<!-- 导入,script标签的type属性一定要设置为module -->
<script type="module">
// 命名式
import { a } from "./export.js";
import {bb} from "./export.js";
import { c as fun } from "./export.js";
console.log(a, bb, fun);
</script>
默认导入导出
// 可导出匿名函数
export default () => {};
export default function(){
return 'world';
}
// 也导出非匿名函数
let d = function () {
console.log('hello');
}
export default d;
// 也可以导出变量
let d = 11;
export default d;
// 但是不可以在声明时导出
// export default let x = () => {}; 报错
<script type="module">
// 默认
import tmp from "./export.js"; // 可以任意起名
console.log(tmp);
</script>
import 与 import() 的区别
- import是静态加载,在编译时就会将需要导入的文件或者变量函数等导进来。
- import()是动态加载,触发事件后才开始加载模块。
异步编排
Promise
- Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
- 从语法上说,Promise是一个对象,从它可以获取异步操作的消息。
- Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。
- Promise特点:
- 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
- 代码示例
- 第一层中调用 resolve 代表一切正常,调用reject 代表出现异常,后续的then中使用return代替resolve传值。
- 第一层执行了 resolve 后才会执行 then 代码块。
- reject被调用后,等待当前代码块执行完,程序会直接执行到catch处。
- 一旦遇到异常,则直接执行到catch处。
- finally接受不到返回值。
<script>
new Promise((resolve, reject)=>{
console.info(`ononon1`);
if(true){
resolve("ok1");
}else{
reject("err");
}
console.info(`ononon2`);
}).then(meg =>{
console.info(`ok2 : ${meg}`);
return 'ok2';
}).then(meg =>{
// throw "An error";
console.info(`ok3 : ${meg}`);
// return 'ok3';
})
.catch(meg =>{
console.info(`error : ${meg}`);
}).finally(meg =>{
console.info(`finally : ${meg}`);
})
</script>
或者
<script>
new Promise((resolve, reject)=>{
console.info(`ononon1`);
if(true){
resolve("ok1");
}else{
reject("err");
}
console.info(`ononon2`);
}).then(meg =>{
console.info(`ok2 : ${meg}`);
return new Promise((resolve, reject)=>{
if(true){
resolve("ok2");
}else{
reject("err2");
}
});
}).then(meg =>{
// throw "An error";
console.info(`ok3 : ${meg}`);
// return new Promise((resolve, reject)=>{
// if(true){
// resolve("ok3");
// }else{
// reject("err3");
// }
// });
})
.catch(meg =>{
console.info(`error : ${meg}`);
}).finally(meg =>{
console.info(`finally : ${meg}`);
})
</script>
- 运行结果
Rest参数
- 主要为 “…” 语法的使用,可代表任意多个参数。
show('one', 'two', 'three', 'four', 'five', 'six');
function show(a, b, ...args) {
console.log(a);//one
console.log(b);//two
console.log(args);//["three", "four", "five", "six"]
}
let arr1 = ['one', 'two'];
let arr2 = [...arr1, 'three', 'four', 'five'];
console.log(arr2);//["one", "two", "three", "four", "five"]
Async、Await
-
函数体前加上async关键字,表示该函数是异步的,此函数会返还一个promise对象。
-
await 可以理解为是 async wait 的简写。await 必须出现在 async 函数内部,不能单独使用。
React
参考网站
- https://zh-hans.reactjs.org/docs/getting-started.html#learn-react
简介
- JSX既不是字符串也不是 HTML,而是一个 JavaScript 的语法扩展。
基本用法
- 可以在JSX大括号内放置任何有效的 JavaScript 表达式
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
- JSX 也是一个表达式,对其取值可得到 JavaScript 对象。
- 在编译之后,JSX 表达式会被转为普通 JavaScript 函数调用。
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
props
- props是properties 的缩写,用于在组件之间传递信息(类似于函数的形参)。
- React 组件接收唯一带有数据的“props”(代表属性)对象与并返回一个 React 元素。
- 子组件可以通过props获取父组件传进来的值,包括但不限于对象、常量、函数、组件。
- 向子组件传值和函数。
<Board squares={current.squares} onClick={(i)=>{this.handleClick(i)}}/>
- 调用并进行向子组件传值和函数。
<Square value1={this.props.squares[i]} onClick = {() => this.props.onClick(i)}/>
state
- state 是私有的,并且完全受控于当前组件(类似于在一个函数内声明的变量)。
- props 和 state 都是普通的 JavaScript 对象。它们都是用来保存信息的,这些信息可以控制组件的渲染输出。
- 数据是向下流动的,组件可以选择把它的 state 作为 props 向下传递到它的子组件中。
- 特点:
- state不可直接修改
- State 的更新可能是异步的
- State 的更新会被合并
- state 定义
constructor(props){
super(props);
this.state = {
xIsNext: true,
// 代表我们当前正在查看哪一项历史记录
stepNumber: 0,
history: [
{
squares: Array(9).fill(null),
}
]
}
}
- state 引用
const current = history[this.state.stepNumber];
- state 修改
this.setState({
history: history.concat([{
squares: squares,
}]),
stepNumber: history.length,
xIsNext : !this.state.xIsNext
});
生命周期
- 教程
- 主要包括三个状态:
- Mounting(挂载):已插入真实 DOM
- Updating(更新):正在被重新渲染
- Unmounting(卸载):已移出真实 DOM
Hook
- 教程
- Hook可以在不编写 class 的情况下使用 state 以及其他的 React 特性。
- React Hooks 必须在 React 函数组件或自定义的 React Hook 函数中调用。
useState
- Hook API 索引
- 返回一个 state,以及更新 state 的函数。
// 在初始渲染期间,返回的状态 (state) 与传入的第一个参数 (initialState) 值相同
const [state, setState] = useState(initialState);
- setState 函数用于更新 state。它接收一个新的 state 值并将组件的一次重新渲染加入队列,在后续的重新渲染中,useState 返回的第一个值将始终是更新后最新的 state。
setState(newState);
- 如果新的 state 需要通过使用先前的 state 计算得出,那么可以将函数传递给 setState。
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
- 如果更新函数返回值与当前 state 完全相同,则随后的重渲染会被完全跳过。