[TOC]
JSX语法
- React的核心机制之一就是可在内存中创建虚拟DOM元素,进而减少对实际DOM的操作从而提升性能,而使用JSX语法可以很方便的创建虚拟DOM
- 组件的render()方法主要用于页面的渲染操作
- JSX提供的JSXTransformer可以将代码中的XML-Like语法编译转换成JavaScript代码
let 和 const 命令
let 声明的变量只在 let 命令所在的代码块内有效
{
let a = 10;
var b = 1;
}
a // ReferenceError
b // 1
- 在 {} 外面使用 let 声明的变量 a,提示
ReferenceError
- 在 {} 外面使用 var 声明的变量 b,可以正常使用变量
let 声明的变量不允许在相同作用于内重复声明
// 报错
function func() {
let a = 10;
var a = 1;
}
// 报错
function func() {
let a = 10;
let a = 1;
}
- 这两种情况都会报错
const 用于声明一个只读的常量,一旦声明,常量的值就不能改变
const PI = 3.14159;
PI = 3; // 报错
- 因为值是不能修改的,所一一旦声明就必须立即初始化,不能留到后面赋值
- 与 let 一样,const 声明的常量也不可重复声明
类
ES6之后添加了对类的支持,引入了 class 关键字。让对象的创建和继承更加直观,也让父类方法的调用、实例化、静态方法和构造函数等更加具体。
继承
class App extends Component {
...
}
方法定义
- 可以直接使用函数名来定义方法
- 方法结尾不需要使用逗号
class App extends Component {
componentWillMount() {}
}
属性类型和默认属性
- ES5:使用 propTypes 和 getDefaultProps() 实现
- ES6:统一使用 static 修饰
class App extends React.Component {
static defaultProps = {
autoPlay: false};
static propTypes = {
autoPlay: React.PropTypes.bool.isRequired};
...
}
箭头函数
主要用来简化函数的书写
一般格式
var f = v => v;
// 等价于
var f = function(v) {
return v;
};
参数:使用圆括号代表参数部分
- 一个参数
var f = () => 5;
// 等价于
var f = function () {
return 5;
};
- 多个参数
var f = (a, b) => a+b;
// 等价于
var f = function (a, b) {
return a+b;
};
函数体:多条语句,使用大括号
var add = (a, b) => {
if (typeof a == 'number' && typeof b == 'number') {
return a+b;
} else {
return 0;
}
}
【注意事项】
- 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。
- 箭头函数不支持 new 命令,否则会抛出错误。
- 不可以使用 arguments 对象,该对象在函数体内不存在,如果要用,可以使用 rest 参数代替。
- 不可以使用 yield 命令,因此箭头函数不能用作 generator 函数。
模块
- ES6 模块的设计思想是尽量
静态化
,是的编译时就能确定模块的依赖关系以及输入和输出的变量。 - 一个模块就是一个
独立的文件
。 - 文件内部的所有变量都
无法被外部获取
。 - 通过
export
命令导出的变量可以被外部获取。
export 和 import
- export 用于对外输出模块
- import 用于导入模块
例子:a.js 文件
var sex = "boy";
var echo = function(value) {
console.log(value);
}
// 导出 sex 变量 和 echo 函数
export {sex, echo}
引用 a.js 文件
import {sex, echo} from "./a.js"
console.log(sex);
// 等价于
echo(sex)
export 和 import 的对应关系
export {sex, echo}
import {sex, echo} from "./a.js"
模块之间的继承,circleplus 模块继承自 circle 模块
export * from 'circle';
export var e = 2.71828182846;
export default function(x) {
return Map.exp(x);
}
-
export *
:导出 circle 模块的所有属性和方法 - 后面两行分别导出 e变量和默认方法
Promise 对象
Promise 的理解
- Promise 是
异步编程
的解决方案。 - Promise 是一个容器,里面保存着某个
未来
才会结束的事件结果
。 - Promise 是一个对象,可以通过
异步
方法获取操作的结果
。 - Promise 修饰的对象,对象状态不受外界影响,一旦状态改变了就不会再变,任何时候都可以得到这个结果。
Promise 的构建
const promise = new Promise(function(resolve, reject) {
// 模拟网络请求成功和失败之后的处理
if (success) {
resolve(value);
} else {
reject(error);
}
}
- 参数是一个函数,这个函数的参数是
resolve
和reject
-
resolve
函数:将 Promise对象的状态从pending
变为resolved
; -
reject
函数:将 Promise对象的状态从pending
变为rejected
;
Promise 的使用
Promise 可以通过 then()
方法将 resolved状态
和 rejected状态
指定回调函数
promise.then(function(value) {
// 成功
}, function(error) {
// 失败
});
- 第一个回调函数:Promise对象的状态为
resolved
时调用,与前面的resolve函数
对应; - 第二个回调函数:Promise对象的状态为
rejected
时调用,与前面的reject函数
对应
async 函数
async 的理解
- async 函数是一个异步操作函数
- 从本质讲,它仍然是一个普通函数,只是将普通函数的
*
替换成了async
,将yield
变成了await
async 的格式
- 函数声明
async function foo() {}
- 表达式声明
var bar = async function() {}
- 对象声明
var obj = { async bazfunction() {} }
- 箭头函数声明
avr fot = async() => {}
async 的返回:
Promise对象
,使用then()
和catch()
处理回调结果
// 声明 getStockPriceByName 函数
async function getStockPriceByName(name) {
let symbol = await getStockSymbol(name);
let price = await getPriceByName(name);
return price;
}
// 使用 getStockPriceByName 函数,在 then 和 catch 中处理结果
getStockPriceByName('goog').then( (result) => {
console.log(result);
}).catch((err)=> {
console.log(err);
})
- await:可以理解为将后面的代码加入一个异步并行队列,不会影响到程序的执行;
- async 返回的 Promise对象,必须要等到所有的 await命令后面的Promise对象都执行完成之后,状态才会改变。这个思想类似于GCD中的调度组;
- 当遇到
return语句
,或者是抛出错误
时,状态也会改变,不需要等await命令后面的Promise对象都执行完;
await 的返回
- 后面跟 Promise对象:Promise对象完成之后返回
- 后面非 Promise对象:直接返回
- 后面跟 thenable对象:当做Promise对象处理
- 后面非 Promise对象
async function f() {
return await 123;
}
f().then(v => console.log(v)); // 直接返回 v 的数值
- 后面跟 thenable对象
class Sleep(timeout) {
constructor(timeout) {
this.timeout = timeout;
}
then(resolve, reject) {...}
}
(async () => {
const acturalTime = await new Sleep(1000);
console.log(acturalTime);
})();
await后面不是 Promise对象也不是一个数值,但是Sleep对象中有实现 then 方法,所以也会将 Sleep对象当做一个 Promise对象来处理。Sleep对象 + then方法 => Promise对象
拦截 reject事件
如果希望某个异步操作失败后不会中断后面的操作,需要拦截这些异常,不让它抛出到reject
-
try...catch
语句拦截:将异常部分放到try...catch
语句结构中
async function myFunction() {
try {
await somethingThatReturnsAPromise();
} catch (err) {
console.log(err);
}
}
-
Promise.catch
语句拦截:将异常部分放到await
后面的Promise对象
的catch()
中处理
async function myFunction() {
await somethingThatReturnsAPromise().catch((err) => {
console.log(err);
});
}
Promise.all():异步并行
- 异步串行:getFoo 完成之后再执行 getFar
let foo = await getFoo();
let far = await getFar();
- 异步并行:getFar 和 getFoo 同时执行
let [foo, far] = await Promise.all([getFoo(), getFar()]);