29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/05、componentapi/src/jsx/SetStateApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class App extends React.Component {
4 | constructor() {
5 | super();
6 |
7 | this.state = {
8 | data: ['setState...']
9 | }
10 |
11 | this.setStateHandler = this.setStateHandler.bind(this);
12 | };
13 |
14 | setStateHandler() {
15 | var item = "setState..."
16 | var myArray = this.state.data;
17 | myArray.push(item)
18 | this.setState({data: myArray})
19 | };
20 |
21 | render() {
22 | return (
23 |
24 |
25 |
State Array: {this.state.data}
26 |
27 | );
28 | }
29 | }
30 |
31 | export default App;
--------------------------------------------------------------------------------
/12、redux/src/reducers/reducers.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux'
2 | import { ADD_TODO } from '../actions/actions'
3 |
4 | function todo(state, action) {
5 | switch (action.type) {
6 |
7 | case ADD_TODO:
8 | return {
9 | id: action.id,
10 | text: action.text,
11 | }
12 |
13 | default:
14 | return state
15 | }
16 | }
17 |
18 | function todos(state = [], action) {
19 | switch (action.type) {
20 |
21 | case ADD_TODO:
22 | return [
23 | ...state,
24 | todo(undefined, action)
25 | ]
26 |
27 | default:
28 | return state
29 | }
30 | }
31 |
32 | const todoApp = combineReducers({
33 | todos
34 | })
35 |
36 | export default todoApp
--------------------------------------------------------------------------------
/12、redux/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "environment_setup",
3 | "version": "1.0.0",
4 | "description": "react enviroment set up",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack-dev-server --hot",
8 | "prod": "webpack -p"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "react": "^15.1.0",
15 | "react-dom": "^15.1.0",
16 | "react-redux": "^4.4.5",
17 | "react-router": "^2.5.1",
18 | "redux": "^3.5.2",
19 | "webpack": "^1.13.1",
20 | "webpack-dev-server": "^1.14.1"
21 | },
22 | "devDependencies": {
23 | "babel-core": "^6.10.4",
24 | "babel-loader": "^6.2.4",
25 | "babel-preset-es2015": "^6.9.0",
26 | "babel-preset-react": "^6.5.0",
27 | "html-webpack-plugin": "^2.21.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/12、redux/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { connect } from 'react-redux'
3 | import { addTodo } from './actions/actions'
4 |
5 | import AddTodo from './components/AddTodo'
6 | import TodoList from './components/TodoList'
7 |
8 | class App extends Component {
9 | render() {
10 | const { dispatch, visibleTodos } = this.props
11 |
12 | return (
13 |
14 |
15 |
17 | dispatch(addTodo(text))}
18 | />
19 |
20 |
21 |
22 |
23 | )
24 | }
25 | }
26 |
27 | function select(state) {
28 | return {
29 | visibleTodos: state.todos
30 | }
31 | }
32 |
33 | export default connect(select)(App)
--------------------------------------------------------------------------------
/13、animations/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "animations",
3 | "version": "1.0.0",
4 | "description": "react animations",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack-dev-server --hot",
8 | "prod": "webpack -p"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "react": "^15.1.0",
15 | "react-addons-css-transition-group": "^15.1.0",
16 | "react-dom": "^15.1.0",
17 | "webpack": "^1.13.1",
18 | "webpack-dev-server": "^1.14.1"
19 | },
20 | "devDependencies": {
21 | "babel-core": "^6.10.4",
22 | "babel-loader": "^6.2.4",
23 | "babel-preset-es2015": "^6.9.0",
24 | "babel-preset-react": "^6.5.0",
25 | "css-loader": "^0.23.1",
26 | "html-webpack-plugin": "^2.21.0",
27 | "style-loader": "^0.13.1"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/05、componentapi/src/main.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | //1、for setState()
5 | //import App from './jsx/SetStateApp.jsx';
6 | //ReactDOM.render(
, document.getElementById('app'))
7 |
8 | //2、for ForceUpdate
9 | //import App from './jsx/PropsApp.jsx';
10 | //import App from './jsx/ForceUpdateApp.jsx';
11 | //ReactDOM.render(
, document.getElementById('app'))
12 |
13 | //3、for Find Dom Node
14 | import App from './jsx/FindDomNodeApp.jsx';
15 | ReactDOM.render(
, document.getElementById('app'));
16 |
17 | //4、state and props App
18 | //import App from './jsx/StateAndPropsApp.jsx';
19 | //ReactDOM.render(
, document.getElementById('app'));
20 |
21 | //4、validating props App
22 | //import App from './jsx/ValidatingPropsApp.jsx';
23 | //ReactDOM.render(
, document.getElementById('app'));
--------------------------------------------------------------------------------
/03、components/src/main.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | //import App from './jsx/StatelessApp.jsx';
4 | // import App from './jsx/StatefulApp.jsx';
5 |
6 | //### 1、无状态函数式组件也支持设置默认的Props类型与值
7 | // import App from './jsx/FunctionApp.jsx';
8 | // ReactDOM.render(
, document.getElementById('app'))
9 |
10 | //### 2、无状态的组件函数中,我们也是可以访问Context
11 | import Text from './jsx/FunctionApp.jsx';
12 | class App extends React.Component {
13 |
14 | getChildContext() {
15 | return {
16 | fontFamily: 'Helvetica Neue'
17 | };
18 | }
19 | render() {
20 | return
Hello World!;
21 | }
22 | }
23 | App.childContextTypes = {
24 | fontFamily: React.PropTypes.string
25 | }
26 |
27 |
28 | // ReactDOM is part of the introduction of React 0.14
29 | ReactDOM.render(
30 |
,
31 | document.getElementById('app')
32 | );
33 |
--------------------------------------------------------------------------------
/13、animations/webpack.config.js:
--------------------------------------------------------------------------------
1 | var HtmlWebpackPlugin = require('html-webpack-plugin')
2 | var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
3 | template: __dirname + '/src/index.html',
4 | filename: 'index.html',
5 | inject: 'body'
6 | });
7 |
8 | var config = {
9 | entry: './src/main.js',
10 |
11 | output: {
12 | path:'./dist',
13 | filename: 'index.js',
14 | },
15 |
16 | devServer: {
17 | inline: true,
18 | port: 8888
19 | },
20 |
21 | module: {
22 | loaders: [{test: /\.jsx?$/,
23 | exclude: /node_modules/,
24 | loader: 'babel',
25 | query: {presets: ['es2015', 'react']}},
26 | {
27 | test: /\.css$/,
28 | loader: 'style!css'
29 | }
30 | ]
31 | },
32 | plugins: [HTMLWebpackPluginConfig]
33 | }
34 |
35 | module.exports = config;
36 |
--------------------------------------------------------------------------------
/09、ref/src/jsx/RefApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | class App extends React.Component {
5 |
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | data: ''
10 | }
11 | this.updateState = this.updateState.bind(this);
12 | this.clearInput = this.clearInput.bind(this);
13 | };
14 |
15 | updateState(e) {
16 | this.setState({data: e.target.value});
17 | }
18 |
19 | clearInput() {
20 | this.setState({data: ''});
21 | ReactDOM.findDOMNode(this.refs.myInput).focus();
22 | }
23 |
24 | render() {
25 | return (
26 |
27 |
29 |
30 |
{this.state.data}
31 |
32 | );
33 | }
34 | }
35 |
36 | export default App;
37 |
--------------------------------------------------------------------------------
/04、state_props/src/main.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | //1、for state App
5 | //import App from './jsx/StateApp.jsx';
6 | //ReactDOM.render(
, document.getElementById('app'))
7 |
8 | //2、for props App
9 | //import App from './jsx/PropsApp.jsx';
10 | //ReactDOM.render(
, document.getElementById('app'));
12 |
13 | //3、for default props App
14 | //import App from './jsx/DefaultPropsApp.jsx';
15 | //ReactDOM.render(
, document.getElementById('app'));
16 |
17 | //4、state and props App
18 | //import App from './jsx/StateAndPropsApp.jsx';
19 | //ReactDOM.render(
, document.getElementById('app'));
20 |
21 | //4、validating props App
22 | // import App from './jsx/ValidatingPropsApp.jsx';
23 | // ReactDOM.render(
, document.getElementById('app'));
24 |
25 | //5、综合小例子(contactsApp)
26 | import App from './jsx/ContactsApp.jsx';
27 | ReactDOM.render(
, document.getElementById('app'));
28 |
--------------------------------------------------------------------------------
/08、events/src/jsx/ChildEventsApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class App extends React.Component {
4 |
5 | constructor(props) {
6 | super(props);
7 |
8 | this.state = {
9 | data: 'Initial data...'
10 | }
11 |
12 | this.updateState = this.updateState.bind(this);
13 | };
14 |
15 | updateState() {
16 | this.setState({data: 'Data updated from the child component...'})
17 | }
18 |
19 | render() {
20 | return (
21 |
22 |
24 |
25 | );
26 | }
27 | }
28 |
29 | class Content extends React.Component {
30 |
31 | render() {
32 | return (
33 |
34 |
35 |
{this.props.myDataProp}
36 |
37 | );
38 | }
39 | }
40 |
41 | export default App;
--------------------------------------------------------------------------------
/04、state_props/src/jsx/StateAndPropsApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class App extends React.Component {
4 | constructor(props) {
5 | super(props);
6 |
7 | this.state = {
8 | header: "Header from state to props...",
9 | "content": "Content from state to props..."
10 | }
11 | }
12 |
13 | render() {
14 | return (
15 |
16 |
19 | );
20 | }
21 | }
22 |
23 | class Header extends React.Component {
24 | render() {
25 | return (
26 |
27 |
{this.props.headerProp}
28 |
29 | );
30 | }
31 | }
32 |
33 | class Content extends React.Component {
34 | render() {
35 | return (
36 |
37 |
{this.props.contentProp}
38 |
39 | );
40 | }
41 | }
42 |
43 | export default App;
--------------------------------------------------------------------------------
/07、forms/src/jsx/ComplexFormApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class App extends React.Component {
4 |
5 | constructor(props) {
6 | super(props);
7 |
8 | this.state = {
9 | data: 'Initial data...'
10 | }
11 |
12 | this.updateState = this.updateState.bind(this);
13 | };
14 |
15 | updateState(e) {
16 | this.setState({data: e.target.value});
17 | }
18 |
19 | render() {
20 | return (
21 |
22 |
24 |
25 | );
26 | }
27 | }
28 |
29 | class Content extends React.Component {
30 |
31 | render() {
32 | return (
33 |
34 |
36 |
{this.props.myDataProp}
37 |
38 | );
39 | }
40 | }
41 | export default App;
--------------------------------------------------------------------------------
/04、state_props/README.md:
--------------------------------------------------------------------------------
1 | ## 启动步骤
2 | * 1、npm install
3 | * 2、npm start,然后可以在浏览器中打开localhost:8888
4 | 或者npm run prod,然后可以到dist目录下打开index.html
5 | 或者直接webpack,然后可以到dist目录下打开index.html
6 |
7 | ## React Components组件介绍
8 |
9 | ### 状态组件(state components)
10 | state状态,仅和自身有关,不受父组件控制
11 |
12 | ### 属性组件(props components)
13 | 由父组件传给子组件属性值
14 |
15 | ### 默认属性(Default Props)
16 | 在组件中可以设置默认的属性值
17 |
18 | ### state和props混合
19 | 组件state状态值当成props属性值传给子组件
20 |
21 | ### 验证属性(Validating props)
22 | 在`App.propTypes`中对属性类型验证,当属性使用中类型不是指定的类型会在`console`控制台上报`warning`提醒,
23 | 在`App.propTypes`指定属性类型后,可以设置`App.defaultProps`给属性默认值
24 |
25 | 1、对于指定`isRequired`的属性,当未设置该属性值的话,控制台会报
26 | ```
27 | "Warning: Failed propType: Required prop `propBool` was not specified in `App`."
28 | ```
29 | 2、当出现和设置的属性值类型不一致的情况,控制台会报
30 | ```
31 | “Warning: Failed propType: Invalid prop `propNumber` of type `string` supplied to `App`, expected `number`.”
32 | ```
33 | ### 自定义验证属性(custom Validating props)
34 | * 1、属性缺失
35 | * 2、属性值长度不够
36 |
37 | ### 综合小例子(contactsApp)
38 | [参考链接](https://github.com/pro-react/sample-code/tree/master/chapter%203/contactsApp)
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 theScoreONE
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/03、components/README.md:
--------------------------------------------------------------------------------
1 | ## 启动步骤
2 | * 1、npm install
3 | * 2、npm start,然后可以在浏览器中打开localhost:8888.
4 |
5 | 或者npm run prod,然后可以到dist目录下打开index.html.
6 |
7 | 或者直接webpack,然后可以到dist目录下打开index.html
8 |
9 | ## React Components组件介绍
10 |
11 | ### 无状态组件(Stateless Components)
12 | 参考**StatelessApp.jsx**
.
13 | 然后将StatelessApp.jsx引入(import)到main.js文件并调用reactDOM.render().
14 |
15 | **顾名思义, 无state状态的组件**
16 |
17 | ### 状态组件(Stateful Components)
18 |
19 | 【注意】给组件`key`属性,当改变代码后,帮助`React`仅更新渲染更改部分而不是全部重新渲染,这对性能有很大的提升
20 |
21 | ### 函数声明组件(Function Components)
22 |
23 | 函数式组件与基于`Class`声明的组件相比,其具有以下特性:
24 |
25 | * 不需要声明类,可以避免大量的譬如`extends`或者`constructor`这样的代码
26 | * 不需要显示声明`this`关键字,在ES6的类声明中往往需要将函数的`this`关键字绑定到当前作用域,而因为函数式声明的特性,我们不需要再强制绑定:
27 | ```javascript
28 | onClick={this.sayHi.bind(this)}>Say Hi
29 | onClick={sayHi}>Say Hi
30 | ```
31 | * 贯彻最佳实践,在`React`组件复用与组合中我们会提到,应当避免在底层的展示性组件中混入对于状态的管理,而应该将状态托管于某个高阶组件或者其他的状态容器中。利用函数式声明组件可以彻底保证不会在组件中进行状态操作。
32 | * 易于理解与测试
33 | * 更佳的性能表现:因为函数式组件中并不需要进行生命周期的管理与状态管理,因此`React`并不需要进行某些特定的检查或者内存分配,从而保证了更好地性能表现。
34 |
35 | #### 高阶组件(Higher-Order Components)
36 | * 查看`HocApp.jsx`
37 |
38 | #### 可重用组件(ReUseable Components)
39 | 应用到refs
40 |
--------------------------------------------------------------------------------
/00、es6-notes/04-Object对象.md:
--------------------------------------------------------------------------------
1 | * 一、ECMAScript 6新标记
2 | * 二、把对象的值复制一份到另一个对象(Object.assign())
3 |
4 | #### 一、ECMAScript 6新标记
5 | [《Object initializer》](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Object_initializer)
6 |
7 | * 1、属性的简写
8 | * 2、方法的简写,"function" 关键字也可以丢掉
9 | * 3、计算的属性名
10 | ```javascript
11 | // 1、Shorthand property names (ES6)
12 | var a = "foo", b = 42, c = {};
13 | var o = { a, b, c };
14 |
15 | // 2、Shorthand method names (ES6)
16 | var o = {
17 | property([parameters]) {},
18 | get property() {},
19 | set property(value) {},
20 | * generator() {}
21 | };
22 | /* 生成器ES5和ES6对比
23 | 1、//EC6提供了一种简明地定义以生成器函数作为值的属性的方法
24 | var o = {
25 | * generator() {
26 | ...........
27 | }
28 | };
29 | 2、ECMAScript 5 中可以这样书写 (需要注意的时 ES5 没有生成器):
30 | var o = {
31 | generatorMethod: function *() {
32 | ...........
33 | }
34 | };
35 | */
36 |
37 | // 3、Computed property names (ES6)
38 | var prop = "foo";
39 | var o = {
40 | [prop]: "hey",
41 | ["b" + "ar"]: "there",
42 | };
43 | ```
44 |
45 | #### 七、把对象的值复制一份到另一个对象(Object.assign())
46 | ```javascript
47 | let num1 = {one: 1};
48 | let num2 = Object.assign({}, num1, {two: 2});
49 | console.log(num1);//{one: 1}
50 | console.log(num2);//{one: 1, two: 2}
51 | ```
52 |
--------------------------------------------------------------------------------
/10、key/src/jsx/KeyApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class App extends React.Component {
4 | constructor() {
5 | super();
6 | this.state = {
7 | data: [
8 | {
9 | component: 'First...',
10 | id: 1
11 | },
12 | {
13 | component: 'Second...',
14 | id: 2
15 | },
16 | {
17 | component: 'Third...',
18 | id: 3
19 | }
20 | ]
21 | }
22 |
23 | }
24 |
25 | render() {
26 | return (
27 |
28 |
29 | {this.state.data.map((dynamicComponent, i) => )}
31 |
32 |
33 | );
34 | }
35 | }
36 |
37 | class Content extends React.Component {
38 | render() {
39 | return (
40 |
41 |
{this.props.componentData.component}
42 |
{this.props.componentData.id}
43 |
44 | );
45 | }
46 | }
47 |
48 | export default App;
--------------------------------------------------------------------------------
/13、animations/src/styles/style.css:
--------------------------------------------------------------------------------
1 | /*bacause " transitionName = "example" "*/
2 | /*
3 | .example-appear {
4 | opacity: 0.01;
5 | }
6 |
7 | .example-appear.example-appear-active {
8 | opacity: 1;
9 | transition: opacity 800ms ease-in;
10 | }
11 |
12 | .example-enter {
13 | opacity: 0.01;
14 | }
15 |
16 | .example-enter.example-enter-active {
17 | opacity: 1;
18 | transition: opacity 500ms ease-in;
19 | }
20 |
21 | .example-leave {
22 | opacity: 1;
23 | }
24 |
25 | .example-leave.example-leave-active {
26 | opacity: 0.01;
27 | transition: opacity 500ms ease-in;
28 | }
29 | */
30 | .example-enter {
31 | opacity: 0;
32 | transform: translateX(-250px);
33 | }
34 | .example-enter.example-enter-active {
35 | opacity: 1;
36 | transform: translateX(0);
37 | transition: 0.3s;
38 | }
39 |
40 |
41 | .example-leave {
42 | opacity: 1;
43 | transform: translateX(0);
44 | }
45 |
46 | .example-leave.example-leave-active {
47 | opacity: 0;
48 | transform: translateX(250px);
49 | transition: 0.3s;
50 | }
51 |
52 | .example-appear {
53 | opacity: 0;
54 | transform: translateX(-250px);
55 | }
56 | .example-appear.example-appear-active {
57 | opacity: 1;
58 | transform: translateX(0);
59 | transition: .3s;
60 | }
61 |
--------------------------------------------------------------------------------
/00、es6-notes/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## 01-变量和参数
3 |
4 | * 一、const、let与原var
5 | * 二、对象和数组解构(Destructuring)
6 | * 三、参数默认值
7 | * 四、Spread展开 / Rest剩余 操作符
8 | * 五、模板语法和分隔符
9 |
10 | ## 02-class类
11 |
12 | * 一、Classes类
13 | * 二、Getters和Setters
14 | * 三、继承(Inheritance)
15 |
16 | ## 03-FunctionalJS函数
17 |
18 | * 一、箭头函数=>
19 | * 二、箭头作为异步callback
20 | * 三、迭代器(Iterators)
21 | * 四、生成器(Generators)
22 |
23 |
24 | ## 04-Object对象
25 |
26 | * 一、ECMAScript 6新标记
27 | * 二、把对象的值复制一份到另一个对象(Object.assign())
28 |
29 | ## 05-array、map、set
30 | * 一、Arrays
31 | * 二、Set 和 WeakSet
32 | * 三、Map 和 WeakMap
33 | * 四、Symbols
34 |
35 | ## 06-Promise
36 |
37 | * 一、Promise
38 | * 二、Promise基础
39 | * 三、Promise的API
40 | * 四、Promise实战
41 |
42 | ## 07-Modules模块化
43 |
44 | * 一、IIFE
45 | * 二、CommonJS 模块化
46 | * 三、AMD
47 | * 四、ES6模块化
48 |
49 |
50 | ## 参考链接
51 |
52 | * [ES6基础](http://blog.csdn.net/mqy1023/article/details/51814629)
53 | * [es6_learning_notes](https://github.com/tayiorbeii/es6_learning_notes)
54 | * [ECMAScript6扫盲](http://www.cnblogs.com/hustskyking/archive/2016/07/11/5659835.html)
55 | * [es6-cheatsheet](https://github.com/DrkSephy/es6-cheatsheet)
56 | * [ES6 In Depth](https://hacks.mozilla.org/page/2/?s=ES6+In+Depth)
57 | * [ES6 In Depth中文翻译版](http://bubkoo.com/2015/06/14/es6-in-depth-an-introduction/)
58 |
--------------------------------------------------------------------------------
/03、components/src/jsx/HocApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const HOC = (InnerComponent) => class extends React.Component {
4 |
5 | constructor() {
6 | super();
7 | this.state = { count: 0 };
8 | }
9 | componentWillMount() {
10 | console.log('componentWillMount');
11 | }
12 | update() {
13 | this.setState({ count: this.state.count + 1 });
14 | }
15 | render() {
16 | return (
17 |
22 | )
23 | }
24 | }
25 |
26 | class App extends React.Component {
27 | render() {
28 | return (
29 |
30 |
31 |
32 | label
33 |
34 | )
35 | }
36 | }
37 |
38 | // 点击 + 1
39 | const Button = HOC((props) =>
40 |
41 | )
42 |
43 | // 划过 + 1
44 | class Label extends React.Component {
45 | componentWillMount() {
46 | console.log('Label componentWillMount');
47 | }
48 | render() {
49 | return (
50 |
51 | )
52 | }
53 | }
54 | const LabelHOC = HOC(Label);
55 |
56 | export default App;
57 |
--------------------------------------------------------------------------------
/03、components/src/jsx/ReUseableApp.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | // import Buttons from './cloneElement/Buttons';
3 | import ReactDom from 'react-dom';
4 |
5 | class App extends React.Component {
6 |
7 | constructor() {
8 | super();
9 | this.state = {
10 | red: 0,
11 | green: 128,
12 | blue: 255
13 | }
14 | this.update = this.update.bind(this);
15 | }
16 |
17 | update(e) {
18 | this.setState({
19 | red: ReactDom.findDOMNode(this.refs.red.refs.inp).value,
20 | green: ReactDom.findDOMNode(this.refs.green.refs.inp).value,
21 | blue: ReactDom.findDOMNode(this.refs.blue.refs.inp).value,
22 | })
23 | }
24 |
25 | render() {
26 | return (
27 |
28 | {this.state.red}
29 | {this.state.green}
30 | {this.state.blue}
31 |
32 | )
33 | }
34 | }
35 |
36 | class Slider extends React.Component {
37 | render() {
38 | return (
39 |
40 |
46 |
47 | )
48 | }
49 | }
50 |
51 | export default App;
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # learn react with es6
2 |
3 | ### 0、[ES6语法基础](./00-es6-notes)
4 |
5 | * 变量和参数
6 | * class类
7 | * Function函数
8 | * Object对象
9 | * Promise
10 | * Modules模块化
11 |
12 | ### 1、[搭建React开发环境](./environment_setup)
13 |
14 | * react开发环境搭建
15 |
16 | ### 2、[JSX语法](./jsx)
17 |
18 | * 内嵌元素(Nested Elements)
19 | * 添加属性(Attributes)
20 | * Js表达式(JavaScript Expressions)
21 | * 样式(Styling)
22 | * 注释(Comments)
23 | * 命名约定(Naming Convention)
24 |
25 | ### 3、[Components组件](./components)
26 |
27 | * 无状态组件(Stateless Components)
28 | * 状态组件(Stateful Components)
29 | * 函数式声明组件(Function Components)
30 | * 可重用组件
31 |
32 | ### 4、[state状态和props属性](./state_props)
33 |
34 | * 状态组件(state components)
35 | * 属性组件(props components)
36 | * 默认属性(Default Props)
37 | * state和props混合
38 | * 验证属性(Validating props)
39 | * 自定义属性验证
40 | * **综合小例子(contactsApp)**
41 |
42 | ### 5、[Components组件的API](./componentapi)
43 |
44 | * 设置状态setState()
45 | * 强制更新ForceUpdate
46 | * 查找DOM节点Find Dom Node
47 |
48 | ### 6、[Components组件生命周期](./lifecyclemethods)
49 |
50 | ### 7、[Forms表单](./forms)
51 |
52 | ### 8、[Event事件](./events)
53 |
54 | ### 9、[ref元素引用](./ref)
55 |
56 | ### 10、[key键属性](./key)
57 |
58 | ### 11、[router路由](./router)
59 |
60 | ### 12、[redux架构](./redux)
61 |
62 | ### 13、[Animations动画](./animations)
63 |
64 | * **
65 |
66 | * [ES6入门](https://github.com/joemaddalone/egghead-react-fundamentals-es6/tree/master/lessons)
67 |
68 | * [react入门](https://egghead.io/courses/react-fundamentals)
69 |
--------------------------------------------------------------------------------
/04、state_props/src/jsx/ValidatingPropsApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class App extends React.Component {
4 | render() {
5 | return (
6 |
7 |
Array: {this.props.propArray}
8 | Bool: {this.props.propBool ? "True..." : "False..."}
9 | Func: {this.props.propFunc(3)}
10 | Number: {this.props.propNumber}
11 | String: {this.props.propString}
12 | Object: {this.props.propObject.objectName1}
13 | Object: {this.props.propObject.objectName2}
14 | Object: {this.props.propObject.objectName3}
15 |
16 | );
17 | }
18 | }
19 |
20 | App.propTypes = {
21 | propArray: React.PropTypes.array.isRequired,
22 | propBool: React.PropTypes.bool.isRequired,
23 | propFunc: React.PropTypes.func,
24 | propNumber: React.PropTypes.number,
25 | propString: React.PropTypes.string,
26 | propObject: React.PropTypes.object
27 | }
28 |
29 | App.defaultProps = {
30 | propArray: [1, 2, 3, 4, 5],
31 | propBool: true,
32 | propFunc: function (e) {
33 | return e * e
34 | },
35 | propNumber: 1,
36 | propString: "String value...",
37 |
38 | propObject: {
39 | objectName1: "objectValue1",
40 | objectName2: "objectValue2",
41 | objectName3: "objectValue3"
42 | }
43 | }
44 |
45 | export default App;
--------------------------------------------------------------------------------
/06、lifecyclemethods/src/jsx/App.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | class App extends React.Component {
4 |
5 | constructor(props) {
6 | super(props);
7 |
8 | this.state = {
9 | data: 0
10 | }
11 |
12 | this.setNewNumber = this.setNewNumber.bind(this)
13 | }
14 |
15 | setNewNumber() {
16 | this.setState({data: this.state.data + 1})
17 | }
18 |
19 | render() {
20 | return (
21 |
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | class Content extends React.Component {
30 |
31 | componentWillMount() {
32 | console.log('Component WILL MOUNT!')
33 | }
34 |
35 | componentDidMount() {
36 | console.log('Component DID MOUNT!')
37 | }
38 |
39 | componentWillReceiveProps(newProps) {
40 | console.log('Component WILL RECIEVE PROPS!')
41 | }
42 |
43 | shouldComponentUpdate(newProps, newState) {
44 | return true;
45 | }
46 |
47 | componentWillUpdate(nextProps, nextState) {
48 | console.log('Component WILL UPDATE!');
49 | }
50 |
51 | componentDidUpdate(prevProps, prevState) {
52 | console.log('Component DID UPDATE!')
53 | }
54 |
55 | componentWillUnmount() {
56 | console.log('Component WILL UNMOUNT!')
57 | }
58 |
59 | render() {
60 | return (
61 |
62 |
{this.props.myNumber}
63 |
64 | );
65 | }
66 | }
67 |
68 | export default App;
69 |
--------------------------------------------------------------------------------
/03、components/src/jsx/StatefulApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | //Parent Component
4 | class App extends React.Component {
5 | constructor() {
6 | super();
7 |
8 | this.state = {
9 | data: [
10 | {
11 | "id": 1,
12 | "name": "Foo",
13 | "age": "20"
14 | },
15 |
16 | {
17 | "id": 2,
18 | "name": "Bar",
19 | "age": "30"
20 | },
21 |
22 | {
23 | "id": 3,
24 | "name": "Baz",
25 | "age": "40"
26 | }
27 | ]
28 | }
29 | }
30 |
31 | render() {
32 | return (
33 |
34 |
35 |
36 |
37 | {this.state.data.map((person, i) => )}
38 |
39 |
40 |
41 | );
42 | }
43 | }
44 | //Header Child Component
45 | class Header extends React.Component {
46 | render() {
47 | return (
48 |
49 |
Header
50 |
51 | );
52 | }
53 | }
54 | //TableRow Child Component
55 | class TableRow extends React.Component {
56 | render() {
57 | return (
58 |
59 | | {this.props.data.id} |
60 | {this.props.data.name} |
61 | {this.props.data.age} |
62 |
63 | );
64 | }
65 | }
66 |
67 | export default App;
68 |
--------------------------------------------------------------------------------
/13、animations/src/jsx/AnimationApp.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
3 |
4 | class App extends React.Component {
5 |
6 | constructor(props) {
7 | super(props);
8 |
9 | this.state = {
10 | items: ['Item 1...', 'Item 2...', 'Item 3...', 'Item 4...']
11 | }
12 |
13 | this.handleAdd = this.handleAdd.bind(this);
14 | };
15 |
16 | handleAdd() {
17 | var newItems = this.state.items.concat([prompt('Create New Item')]);
18 | this.setState({items: newItems});
19 | }
20 |
21 | handleRemove(i) {
22 | var newItems = this.state.items.slice();
23 | newItems.splice(i, 1);
24 | this.setState({items: newItems});
25 | }
26 |
27 | render() {
28 | var items = this.state.items.map(function (item, i) {
29 | return (
30 |
31 | {item}
32 |
33 | );
34 |
35 | }.bind(this));
36 |
37 | return (
38 |
39 |
40 |
41 |
46 | {items}
47 |
48 |
49 | );
50 | }
51 | }
52 |
53 | export default App;
54 |
--------------------------------------------------------------------------------
/01、environment_setup/README.md:
--------------------------------------------------------------------------------
1 | ## 搭建步骤
2 | 准备:本机必须先安装nodejs环境,可命令行键入:node -v //查看是否安装&node版本信息
3 | ### step1— — 安装全局包
4 | ```bash
5 | 如:webpack
6 | window下需“以管理者身份运行cmd”,然后: npm install -g webpack
7 | ```
8 | ### step2:创建react项目并初始化package.json管理包
9 | * mkdir reactApp
10 | * npm init --yes
11 | ### step3: 添加依赖和插件
12 | ```bash
13 | //1、webpack构建项目
14 | npm install webpack --save
15 | npm install webpack-dev-server --save
16 | //2、react核心库
17 | npm install react --save
18 | npm install react-dom --save
19 | //3、babel转译es6
20 | npm install babel-core --save-dev
21 | npm install babel-loader --save-dev
22 | npm install babel-preset-react --save-dev
23 | npm install babel-preset-es2015 --save-dev
24 | //4、转译后输出的xxx.js插入inject到index.html中的插件
25 | npm install html-webpack-plugin --save-dev
26 | ```
27 | ### step4:创建项目文件,es6语法的jsx和构建包配置webpack.config.js
28 | 项目目录结构为:
29 | ```
30 | .
31 | ├── src
32 | ├── jsx
33 | ├── App.jsx
34 | ├── main.js
35 | ├── index.html
36 | ├── package.json
37 | ├── README.md
38 | ├── webpack.cofig.js
39 | ```
40 | ### step5:设置Compiler、 Server和Loaders
41 | ```bash
42 | 1、webpack.config.js文件中构建配置
43 | a、entry,入口文件main.js
44 | b、output,指定输出后的index.js
45 | c、devServer,设置服务器端口
46 | d、babel,loader使用es2015和react presets
47 | e、html-webpack-plugin插件,让转译后的index.js插入inject到index.html的body下,并复制indx.html到输出的dist目录
48 | 2、修改package.json中的"script"
49 | a、"start": "webpack-dev-server --hot"
50 | 命令行:npm start可以启动服务器,其中“--hot”命令是当修改源码后不用重新刷新浏览器,也能实时重新加载到最新源码
51 | b、"prod": "webpack -p"
52 | 命令行:npm run prod可以输出生产情况下的构建包,可以看到生成dist目录并有index.html和index.js
53 | ```
54 | ### step6:编写index.html和App.jsx还有入口的main.js
55 |
56 | ### step7:启动服务器
57 | 编写npm script
58 | ```
59 | npm start,然后可以在浏览器中打开localhost:8888
60 | 或者npm run prod,然后可以到dist目录下打开index.html
61 | ```
62 | **==> 能在浏览器中看到“Hello World!!!”,说明React开发环境搭建成功了!!**
63 |
64 | * **后续React开发均在本次的搭建React环境基础上**
65 |
--------------------------------------------------------------------------------
/00、es6-notes/02-class类.md:
--------------------------------------------------------------------------------
1 |
2 | * 一、Classes类
3 | * 二、Getters和Setters
4 | * 三、继承(Inheritance)
5 |
6 | #### 一、Classes类
7 | ES6中的class类是基于Javascript原有的原型(prototype)继承(inheritance),
8 | class并不是新的一种面向对象js模型,而是提供了更简单、更清晰创建对象和处理继承关系的语法【typeof Employee; //'function'】
9 | 1、老方法编写一个类
10 | ```javascript
11 | var Employee = function() { };
12 | Employee.prototype = { //prototype
13 | doSomething: function(){
14 | return "done!";
15 | }
16 | };
17 | var e = new Employee();
18 | ```
19 | 2、ES6编写类
20 | ```javascript
21 | class Employee {
22 | doSomething() {
23 | return "complete!";
24 | }
25 | doSomethingElse() {
26 | return "also complete!"
27 | }
28 | }
29 | typeof Employee; // 'function'
30 | var e = new Employee();
31 | e.doSomething(); // "complete!"
32 | ```
33 | 3、Constructor构造器
34 | ```javascript
35 | class Employee {
36 | constructor(name) {
37 | this._name = name;
38 | }
39 | doSomething() {
40 | return "complete!";
41 | }
42 | getName() {
43 | return this._name;
44 | }
45 | }
46 |
47 | let e1 = new Employee("Taylor");
48 | let e2 = new Employee("Charles");
49 |
50 | e1.getName(); // "Taylor"
51 | e2.getName(); // "Charles"
52 | ```
53 | #### 二、Getters和Setters
54 | ```javascript
55 | class Person {
56 | constructor(name) {
57 | this.name = name;
58 | }
59 | get name() {
60 | return this._name;
61 | }
62 | set name(newValue) {
63 | this._name = newValue;
64 | }
65 | }
66 | let e1 = new Person("Taylor");
67 | console.log(e1.name); // "Taylor"
68 | ```
69 | #### 三、继承(Inheritance)
70 | extends继承、super父类、
71 | ```javascript
72 | //在Getters和Setters的代码基础上
73 | class Employee extends Person {
74 | constructor(title, name) {
75 | super(name);
76 | this._title = title;
77 | }
78 | doWork() {
79 | return `${this._name} is working`; // uses ES6's literal syntax
80 | }
81 | }
82 |
83 | let p1 = new Person("Taylor");
84 | let e1 = new Employee("Chris");
85 | e1.doWork(); // "Chris is working"
86 | ```
87 |
--------------------------------------------------------------------------------
/06、lifecyclemethods/README.md:
--------------------------------------------------------------------------------
1 | ## 启动步骤
2 | * 1、npm install
3 | * 2、npm start, 然后可以在浏览器中打开localhost:8888.
4 | 或者npm run prod,然后可以到dist目录下打开index.html.看package.json中对应的该命令
5 |
6 | ## React Components组件生命周期
7 |
8 | #### 一、初始化及挂载阶段
9 | * 1、这是组件类的构造函数,通常在此初始化state数据模型。
10 | ```javascript
11 | constructor(props) {
12 | super(props);
13 | this.state = {
14 | //key : value
15 | };
16 | }
17 | ```
18 | * 2、componentWillMount在rendering渲染前执行,在服务端和客户端都会被执行
19 | ```javascript
20 | componentWillMount() {
21 |
22 | }
23 | ```
24 | * 3、componentDidMount在客户端第一次render渲染后被执行,通知组件已经加载完成,虚拟DOM已构建完成,
25 | 可以在该函数中Ajax请求、修改DOM、setTimeout或setInterval,还可更新state触发组件中其他生命周期方法.
26 | ```javascript
27 | componentDidMount() {
28 | this.props.fetchAirports();
29 | }
30 | ```
31 | #### 二、运行期阶段
32 | * 1、componentWillReceiveProps, 通常在此方法接收新的props值,重新设置state.
33 | ```javascript
34 | componentWillReceiveProps(nextProps) {
35 | this.setState({
36 | //key : value
37 | });
38 | }
39 | ```
40 | * 2、shouldComponentUpdate:接受新props或state时调用; 如果该方法返回false,则componentWillUpdate(nextProps, nextState)及其之后执行的方法都不会执行,组件则不会进行重新渲染。
41 | ```javascript
42 | shouldComponentUpdate(nextProps, nextState) {
43 | // return nextProps.val % 5 === 0;
44 | return nextProps.id !== this.props.id;
45 | }
46 | ```
47 | * 3、componentWillUpdate,在shouldComponentUpdate返回true后立刻调用,rendering渲染方法前被调用
48 | ```javascript
49 | componentWillUpdate(nextProps, nextState){
50 | let originAndDestinationSelected = nextProps.origin && nextProps.destination;
51 | let selectionHasChangedSinceLastUpdate = nextProps.origin !== this.props.origin ||
52 | nextProps.destination !== this.props.destination;
53 | if(originAndDestinationSelected && selectionHasChangedSinceLastUpdate){
54 | this.props.fetchTickets(nextProps.origin, nextProps.destination);
55 | }
56 | }
57 | ```
58 | * 4、componentDidUpdate,在render()渲染方法后被调用
59 | ```
60 | componentDidUpdate(preProps, preState) {
61 | console.log(`preProps: ${preProps.val}`); // 打印后面的render的前一个值
62 | }
63 | ```
64 | * **5、render方法用于渲染组件。在初始化阶段和运行期阶段都会执行**
65 | ```javascript
66 | render() {
67 | return(
68 |
69 | );
70 | }
71 | ```
72 | ### 三、卸载阶段
73 | * 1、componentWillUnmount,组件从DOM节点中被卸载unmounted时被调用,一般用于clearInterval等
74 | ```javascript
75 | componentWillUnmount() {
76 |
77 | }
78 | ```
79 |
80 | ## 组件生命周期例子分析
81 | 
82 |
83 | * 1、组件渲染成功,会调用componentWillMount和componentDidMount
84 |
85 | * 2、每点击一次**INCREMENT**按钮,更改props属性值,都会调用以下三个方法打印出:
86 | ```bash
87 | Component WILL RECIEVE PROPS!
88 | Component WILL UPDATE!
89 | Component DID UPDATE!
90 | ```
91 | * 3、十秒后卸载组件,调用unmout打印出:
92 | ```bash
93 | Component WILL UNMOUNT!
94 | ```
95 |
96 | ## 更多链接
97 | [React入门笔记(二) — 组件的生命周期](http://blog.csdn.net/mqy1023/article/details/51571320)
98 |
--------------------------------------------------------------------------------
/00、es6-notes/07-Modules模块化.md:
--------------------------------------------------------------------------------
1 | * 一、IIFE
2 | * 二、CommonJS 模块化
3 | * 三、AMD
4 | * 四、ES6模块化
5 |
6 | #### 一、立即自执行函数表达式immediately invoked function expression (IIFE)
7 | 1、通过target.Employee = Employee将其绑定给浏览器窗口, 全局暴露
8 | 2、privateDoWork只在IIFE的closure中可见
9 | ```javascript
10 | (function(target) {
11 | var privateDoWork = function(name) {
12 | return name + " is working";
13 | };
14 |
15 | var Employee = function(name) {
16 | this.name = name;
17 | }
18 |
19 | Employee.prototype = {
20 | doWork: function() {
21 | return privateDoWork(this.name);
22 | }
23 | }
24 |
25 | target.Employee = Employee;
26 | }(window));
27 | ```
28 | #### 二、CommonJS
29 | exports 和 require.
30 | ```javascript
31 | var privateDoWork = function(name) {
32 | return name + " is working";
33 | }
34 |
35 | var Employee = function(name) {
36 | this.name = name;
37 | }
38 |
39 | Employee.prototype = {
40 | doWork: function() {
41 | return privateDoWork(this.name);
42 | }
43 | }
44 |
45 | exports.Employee = Employee;
46 | ```
47 | ```javascript
48 | var Employee = require('./Employee').Employee;
49 |
50 | var e1 = new Employee("Taylor");
51 | console.log(e1.doWork()); // "Taylor is working"
52 | ```
53 | #### 三、AMD
54 | ```javascript
55 | // employee.js
56 | define(function() {
57 | var privateDoWork = function() {
58 | // ...
59 | }
60 | var Employee = function(name) {
61 | // ...
62 | }
63 | return Employee;
64 | });
65 | ```
66 | ```javascript
67 | define(["employee"], function(Employee){
68 | var e = new Employee("Taylor");
69 | });
70 | ```
71 | #### 四、ES6
72 | 一个ES6模块(module)是一个包含js代码的文件
73 | 1、Export
74 | 可以export出函数、class、var、let、const
75 | ```javascript
76 | //utility.js, 暴露一个对象列表
77 | function generateRandom() {
78 | return Math.random();
79 | }
80 | function sum(a, b) {
81 | return a + b;
82 | }
83 | export { generateRandom, sum }
84 | ```
85 | 2、Default Exports
86 | ```javascript
87 | var utils = {
88 | generateRandom() {
89 | return Math.random();
90 | },
91 | sum(a, b) {
92 | return a + b;
93 | }
94 | };
95 | export default utils;
96 | ```
97 | 3、Import
98 | ```javascript
99 | import { generateRandom, sum } from 'utility';
100 | console.log(generateRandom()); //logs a random number
101 | console.log(sum(1, 2)); //3
102 |
103 | //import default导入默认,不需要{ }
104 | //import utils from 'utility';
105 | //console.log(utils.generateRandom()); //logs a random number //console.log(utils.sum(1, 2)); //3
106 | ```
107 | 4、重命名导入:
108 | ```javascript
109 | import {
110 | sumTwo as addTwoNumbers,
111 | sumThree as sumThreeNumbers
112 | } from 'math/addition';
113 | ```
114 | 5、导入所有的东西(整体加载):
115 | ```javascript
116 | import * as util from 'math/addition';
117 |
118 | //可以从一个模块中导入一个值的列表:
119 | import * as additionUtil from 'math/addition';
120 | const { sumTwo, sumThree } = additionUtil;
121 | ```
122 | 6、混合默认default的导入和混合导入
123 | ```javascript
124 | import defaultFoo, { foo1, foo2 } from 'foos';
125 |
126 | //react的导入
127 | import React, { Component, PropTypes } from 'react';
128 | ```
129 |
--------------------------------------------------------------------------------
/02、jsx/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## 启动步骤
3 | * 1、npm install
4 | * 2、npm start,然后可以在浏览器中打开localhost:8888
5 | 或者npm run prod,然后可以到dist目录下打开index.html
6 | 或者直接webpack,然后可以到dist目录下打开index.html
7 |
8 | ## JSX介绍
9 |
10 | ### 内嵌元素(Nested Elements)
11 | **App.jsx**
12 | ```javascript
13 | import React from 'react';
14 |
15 | class App extends React.Component {
16 | render() {
17 | return (
18 |
19 |
Header
20 |
Content
21 |
This is the content!!!
22 |
23 | );
24 | }
25 | }
26 |
27 | export default App;
28 | ```
29 | ### 添加属性(Attributes)
30 | 可以添加自定义的属性,不过需要需加前缀data-xxx,如下,给元素添加一个自定义属性data-myattribute
31 | **App.jsx**
32 | ```javascript
33 | import React from 'react';
34 |
35 | class App extends React.Component {
36 | render() {
37 | return (
38 |
39 |
Header
40 |
Content
41 |
This is the content!!!
42 |
43 | );
44 | }
45 | }
46 |
47 | export default App;
48 | ```
49 | ### Js表达式(JavaScript Expressions)
50 | 可以在JSX中嵌入js表达式,只需要用{}来包裹,如下将在浏览器中渲染显示出2
51 | **App.jsx**
52 | ```bash
53 |
{1+1}
54 | ```
55 | 同样可以在JSX中使用if else表达式
56 | ```javascript
57 |
{i === 1 ? 'True!' : 'False'}
58 | {condition ?
Hello JSX (The condition was true) : null}
59 | ```
60 | ### 样式(Styling)
61 | 样式使用驼峰式语法,数字后默认px
62 | ```javascript
63 | import React from 'react';
64 |
65 | class App extends React.Component {
66 | render() {
67 | var myStyle = {
68 | fontSize: 100,
69 | color: '#FF0000'
70 | }
71 | return (
72 |
73 |
Header
74 |
75 | );
76 | }
77 | }
78 | export default App;
79 | ```
80 | ### 注释(Comments)
81 | 可以用单行//或多行/*...*/来注释,当在子元素中写注释,最好包裹上{}
82 |
83 | ```javascript
84 | import React from 'react';
85 | class App extends React.Component {
86 | render() {
87 | return (
88 |
89 |
Header
90 | {//单行注释...}
91 | {/*多行注释...*/}
92 |
93 | );
94 | }
95 | }
96 | export default App;
97 | ```
98 |
99 | ### 不同点
100 |
101 | * 1、HTML标签使用小写,而React组件以**大写**字母为首命名
102 | * 2、`html`的`class`与`for`属性在`js`里是保留字,所以`jsx`里要用别名`className`与`htmlFor`
103 | * 3、checkbox中正确使用checked属性
104 | ```javascript
105 | //在其他前端模板引擎中,可以这么做,因为是拼接字符串
106 | var checkbox =
107 | //但在jsx中,这是错误的,因为无法构成键值对,要有个key=value的格式,所以得这样
108 | var checkbox =
109 | ```
110 | * 4、不能直接写并列的元素
111 | ```javascript
112 | //这样写是错误的
113 | var MyComponent = React.createClass({
114 | render: function() {
115 | return
first div
second div
116 | }
117 | })
118 | //因为编译后,return 两个函数调用,就算不报错,也只调用第一个函数,不合意图
119 | var MyComponent = React.createClass({
120 | render: function() {
121 | return React.createElement('div', null, 'first div') React.createElement('div', null, 'second div')
122 | }
123 | })
124 | ```
125 | * 5、jsx要求标签一定要闭合,html5中不强制要求闭合的,在jsx也都要闭合,以便识别
126 | * 6、封装的组件要用大写字母开头,以便跟html标签区分。
127 |
--------------------------------------------------------------------------------
/04、state_props/src/jsx/ContactsApp.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | const contactsData = require('./../public/contacts.json'); //获取json数据
3 |
4 | class ContactsAppContainer extends Component {
5 | constructor(){
6 | super();
7 | this.state={
8 | contacts: []
9 | };
10 | }
11 |
12 | componentDidMount(){
13 | this.setState({contacts: contactsData.datas});
14 | }
15 |
16 | render(){
17 | return (
18 |
19 | );
20 | }
21 | }
22 |
23 | // Renders a SearchBar and a ContactList
24 | // Passes down filterText state and handleUserInput callback as props
25 | class ContactsApp extends Component {
26 | constructor(){
27 | super();
28 | this.state={
29 | filterText: ''
30 | };
31 | }
32 |
33 | handleUserInput(searchText){
34 | this.setState({filterText: searchText})
35 | }
36 |
37 | render(){
38 | return(
39 |
40 |
42 |
44 |
45 | )
46 | }
47 | }
48 | ContactsApp.propTypes = {
49 | contacts: PropTypes.arrayOf(PropTypes.object)
50 | }
51 |
52 |
53 | // Pure component that receives 2 props from the parent
54 | // filterText (string) and onUserInput (callback function)
55 | class SearchBar extends Component {
56 | handleChange(event){
57 | this.props.onUserInput(event.target.value)
58 | }
59 |
60 | render(){
61 | return
65 | }
66 | }
67 | SearchBar.propTypes = {
68 | onUserInput: PropTypes.func.isRequired,
69 | filterText: PropTypes.string.isRequired
70 | }
71 |
72 | // Pure component that receives both contacts and filterText as props
73 | // The component is responsible for actualy filtering the
74 | // contacts before displaying them.
75 | // It's considered a pure component because given the same
76 | // contacts and filterText props the output will always be the same.
77 | class ContactList extends Component {
78 | render(){
79 | //过滤contacts中数据
80 | let filteredContacts = this.props.contacts.filter(
81 | (contact) => contact.name.indexOf(this.props.filterText) !== -1
82 | );
83 | return(
84 |
85 | {filteredContacts.map(
86 | (contact) =>
89 | )}
90 |
91 | )
92 | }
93 | }
94 | ContactList.propTypes = {
95 | contacts: PropTypes.arrayOf(PropTypes.object),
96 | filterText: PropTypes.string.isRequired
97 | }
98 |
99 | class ContactItem extends Component {
100 | render() {
101 | return
{this.props.name} - - {this.props.email}
102 | }
103 | }
104 | ContactItem.propTypes = {
105 | name: PropTypes.string.isRequired,
106 | email: PropTypes.string.isRequired
107 | }
108 |
109 | export default ContactsAppContainer;
110 |
--------------------------------------------------------------------------------
/00、es6-notes/05-array、map、set.md:
--------------------------------------------------------------------------------
1 | * 一、Arrays
2 | * 二、Set 和 WeakSet
3 | * 三、Map 和 WeakMap
4 | * 四、Symbols
5 |
6 | #### 一、Arrays
7 | 1、find
8 | ```javascript
9 | var ary = [1, 5, 10];
10 | var match = ary.find(item => item > 8);
11 | match; // 10
12 | ```
13 | 2、findIndex
14 | 返回符合条件第一个index
15 | ```javascript
16 | var ary = [1, 5, 10];
17 | var match = ary.findIndex(item => item > 3);
18 | match; // 1
19 | ```
20 | 3、fill填充
21 | ```javascript
22 | var ary = [1, 2, 3, 4, 5];
23 | ary.fill('a');
24 | ary; // ['a', 'a', 'a', 'a', 'a']
25 |
26 | ary.fill('a', 2, 3) // 只需要下表为index的数为 'a'
27 | ```
28 | 4、copyWithin
29 | ```javascript
30 | var ary = [1, 2, 3, 4]; // we want [1, 2, 1, 2]
31 |
32 | // First parameter as the target (index 2)
33 | // Second parameter is where you copy from (index 0)
34 | // A third parameter would be the stopping point.
35 | ary.copyWithin(2, 0); // [1, 2, 1, 2]
36 | ary.copyWithin(2, 0, 1); // [1, 2, 1, 4]
37 | ary.copyWithin(2, 0, 2); // [1, 2, 1, 2]
38 |
39 | // Can also use negative indexes:
40 | ary.copyWithin(0, -2); // [3, 4, 3, 4]
41 | ```
42 | 5、of
43 | ```javascript
44 | var ary = new Array(3); //[, , ]
45 | var ofAry = Array.of(3); // [3]
46 |
47 | ary.length; // 3
48 | ofAry.length; // 1
49 | ```
50 | 6、entries and keys
51 | ```javascript
52 | var a = ['Joe', 'Jim', 'John'];
53 | var entries = a.entries();
54 |
55 | var firstEntry = entries.next().value;
56 | firstEntry[0]; // 0 (the index)
57 | firstEntry[1]; // 'Joe' (the value)
58 |
59 | // `keys` are the indexes
60 | var firstKey = keys.next().value;
61 | firstKey; // 0
62 | ```
63 | 7、forEach遍历 和 filter过滤
64 | ```javascript
65 | let arrs = [1, 2, 3];
66 | arrs.forEach(arr => {
67 | console.log(arr + 1); // 打印出 2 3 4
68 | });
69 |
70 | arrs = arrs.filter(a => a != 3);
71 | console.log(arrs);// [1, 2]
72 | ```
73 |
74 | #### 二、Set 和 WeakSet
75 | Set 对象是一组不重复的值,重复的值将被忽略,值类型可以是原始类型和引用类型:
76 | ```javascript
77 | let mySet = new Set([1, 1, 2, 2, 3, 3]);
78 | mySet.size; // 3
79 | mySet.has(1); // true
80 | mySet.add('strings');
81 | mySet.add({ a: 1, b:2 });
82 | ```
83 | WeakSet 对象可以让你在一个集合中保存对象的弱引用,在 WeakSet 中的对象只允许出现一次:
84 |
85 |
86 | #### 三、Map 和 WeakMap
87 | ES6 中两种新的数据结构集:Map 和 WeakMap。事实上每个对象都可以看作是一个 Map。
88 | 一个对象由多个 key-val 对构成,在 Map 中,任何类型都可以作为对象的 key
89 | entries
90 | ```javascript
91 | var map = new Map();
92 | map.set('name', 'Joe');
93 | var items = map.entries();
94 | var first = items.next().value;
95 | first[0]; // 'name'
96 | first[1]; // 'Joe'
97 | ```
98 | values和keys
99 | ```javascript
100 | var map = new Map();
101 | map.set(1, 'a');
102 | var values = map.values();
103 | var first = values.next().value;
104 | first; // 'a'
105 |
106 | var keys = map.keys();
107 | var firstKey = keys.next().value;
108 | firstKey; // 1
109 | ```
110 |
111 | #### 四、Symbols
112 | 1、Symbol()
113 | Symbols 是不可改变并且是第一无二的,可以在任意哈希中作一个key。
114 | 调用 Symbol() 或者 Symbol(description) 可以创造一个第一无二的符号,
115 | 但是在全局是看不到的。Symbol() 的一个使用情况是给一个类或者命名空间打上补丁,
116 | 但是可以确定的是你不会去更新它。比如,你想给 React.Component 类添加一个 refreshComponent 方法,
117 | 但是可以确定的是你不会在之后更新这个方法:
118 | ```javascript
119 | const refreshComponent = Symbol();
120 | React.Component.prototype[refreshComponent] = () => {
121 | // do something
122 | }
123 | ```
124 | 2、Symbol.for(key)
125 | Symbol.for(key) 同样会创造一个独一无二并且不可改变的 Symbol,但是它可以全局看到,
126 | 两个相同的调用 Symbol.for(key) 会返回同一个 Symbol 类:
127 | ```javascript
128 | Symbol('foo') === Symbol('foo') // false
129 | Symbol.for('foo') === Symbol('foo') // false
130 | Symbol.for('foo') === Symbol.for('foo') // true
131 | ```
132 | 在另一个库中:
133 | ```javascript
134 | const specialRead = Symbol.for('specialRead');
135 |
136 | class SomeReadableType {
137 | [specialRead]() {
138 | const reader = createSomeReaderFrom(this);
139 | return reader;
140 | }
141 | }
142 | ```
143 |
--------------------------------------------------------------------------------
/00、es6-notes/06-Promise.md:
--------------------------------------------------------------------------------
1 | * 一、Promise
2 | * 二、Promise基础
3 | * 三、Promise的API
4 | * 四、Promise实战
5 |
6 | #### 一、Promise
7 | 1、`Promise`,首先是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的`API`,可供进一步处理。
8 |
9 | 2、`Promise`对象只有三种状态。
10 |
11 | * 异步操作“未完成”(pending)
12 | * 异步操作“已完成”(resolved,又称fulfilled)
13 | * 异步操作“失败”(rejected)
14 |
15 | `Promise`对象的最终结果只有两种
16 |
17 | * 异步操作成功,Promise对象传回一个值,状态变为resolved。
18 | * 异步操作失败,Promise对象抛出一个错误,状态变为rejected。
19 |
20 | 3、`Promise`的优点:
21 |
22 | * 让回调函数变成了规范的链式写法,程序流程可以看得很清楚
23 | * 为多个回调函数中抛出的错误统一指定处理方法
24 | * `Promise` 可以让我们远离平行的代码(回调地狱)
25 | ```javascript
26 | step1(function (value1) {
27 | step2(value1, function (value2) {
28 | step3(value2, function (value3) {
29 | });
30 | });
31 | });
32 | });
33 | ```
34 | 转变成垂直代码:
35 | ```javascript
36 | (new Promise(step1))
37 | .then(step2)
38 | .then(step3, value3 => {
39 | // Do something with value3
40 | });
41 | ```
42 |
43 | #### 二、Promise基础
44 |
45 | 1、新建Promise
46 | Promise是一个构造函数(类),可以使用new运算符新建一个实例,然后就可以使用了,构造函数接受一个函数作为参数。
47 | ```javascript
48 | var p = new Promise((resolve, reject) => {
49 | if (/* condition */) {
50 | resolve(/* value */); // fulfilled successfully
51 | } else {
52 | reject(new Error('/* reason */')); // error, rejected
53 | }
54 | });
55 | p.then((value) => {
56 | console.log('p success', value);
57 | });
58 | p.catch((reason) => {
59 | console.log(reason);
60 | });
61 | ```
62 | 两个处理器,`resolve`(当Promise是 fulfilled 时的回调)和 `reject`(当Promise是 rejected 时的回调)
63 |
64 | 2、`.then()`方法
65 |
66 | * 当创建好的promise执行完成后,其状态会变成 `resolved` 或者 `reject`
67 | * 可以通过then方法定制状态变化后的回调函数,该方法接受两个参数,
68 | 第一个是异步操作成功处理 `resolved` 状态的回调,另一个是异步操作失败处理 `rejected` 状态的回调:
69 | ```javascript
70 | p.then((val) => console.log("Promise Resolved", val),
71 | (err) => console.log("Promise Rejected", err));
72 | //ES5写法
73 | p.then(function(value) {
74 | // success
75 | }, function(reason) {
76 | // failure
77 | });
78 | ```
79 |
80 | 3、多个promise交互
81 | ```javascript
82 | var previousPromise = new Promise(function(resolve, reject){
83 | resolve(3);
84 | });
85 |
86 | var promise = new Promise(function(resolve, reject) {
87 | resolve( previousPromise );
88 | });
89 |
90 | promise.then( function(data) {
91 | console.log(data); // 3
92 | })
93 | ```
94 |
95 | #### 三、Promise的API
96 |
97 | * 1、Promise.all
98 | Promise.all(iterable) 方法返回一个promise,该promise会在iterable参数内的**所有promise都被解决**后被解决
99 |
100 | * 2、Promise.race
101 | Promise.race(iterable)方法返回一个promise,这个promise在iterable中的**任意一个promise被解决或拒绝**后,立刻以相同的解决值被解决或以相同的拒绝原因被拒绝
102 |
103 | * 3、Promise.reject
104 | Promise.reject(reason)方法返回一个用reason拒绝的Promise。
105 |
106 | * 4、Promise.resolve
107 | Promise.resolve(value)方法返回一个以给定值resolve掉的Promise对象。
108 |
109 | #### 四、Promise实战
110 |
111 | 1、综合实战
112 | ```javascript
113 | // 1000ms 后success
114 | var p1 = new Promise((resolve, reject) => {
115 | window.setTimeout(() => {resolve(123);}, 1000);
116 | });
117 |
118 | p1.then((data) => {
119 | console.log('p1 success', data);
120 | });
121 |
122 | // 2000ms 后success
123 | var p2 = new Promise((resolve, reject) => {
124 | window.setTimeout(() => {resolve(456);}, 2000);
125 | });
126 |
127 | p2.then((data) => {
128 | console.log('p2 success', data);
129 | });
130 |
131 | var pa = Promise.all([p1, p2]);
132 | var pr = Promise.race([p1, p2]);
133 |
134 | pa.then((data) => {
135 | console.log('pa success', data);
136 | });
137 |
138 | pr.then((data) => {
139 | console.log('pr success', data);
140 | });
141 | ```
142 | 上面的代码输出如下:
143 | ```
144 | // 1000ms
145 | p1 success 123
146 | pr success 123
147 |
148 | // 2000ms
149 | p2 success 456
150 | pa success [123, 456]
151 | ```
152 | 2、用ajax加载图片
153 | ```javascript
154 | function imgLoad(url) {
155 | return new Promise(function(resolve, reject) {
156 | var request = new XMLHttpRequest();
157 | request.open('GET', url);
158 | request.responseType = 'blob';
159 | request.onload = function() {
160 | if (request.status === 200) {
161 | resolve(request.response);
162 | } else {
163 | reject(new Error('图片加载失败:' + request.statusText));
164 | }
165 | };
166 | request.onerror = function() {
167 | reject(new Error('发生网络错误'));
168 | };
169 | request.send();
170 | });
171 | }
172 |
173 | var img = document.findElementById("imgId");
174 | imgLoad("http://xxxx.com").then(data => {
175 | img.src = data;
176 | });
177 | ```
178 | 3、项目中请求实战
179 | ```javascript
180 | let urls = [
181 | '/api/commits',
182 | '/api/issues/opened',
183 | '/api/issues/completed',
184 | '/api/pullrequests'
185 | ];
186 |
187 | let promises = urls.map((url) => {
188 | return new Promise((resolve, reject) => {
189 | $.ajax({ url: url })
190 | .done((data) => {
191 | resolve(data);
192 | });
193 | });
194 | });
195 |
196 | Promise.all(promises)
197 | .then((results) => {
198 | // Do something with results of all our promises
199 | });
200 | ```
201 |
--------------------------------------------------------------------------------
/00、es6-notes/01-变量和参数.md:
--------------------------------------------------------------------------------
1 |
2 | * 一、const、let与原var
3 | * 二、对象和数组解构(Destructuring)
4 | * 三、参数默认值
5 | * 四、Spread展开 / Rest剩余 操作符
6 | * 五、模板语法和分隔符
7 |
8 | #### 一、const、let与原var
9 | 1、相比`es5`的`var`是相对函数作用域范围,`const`和`let`都是相对块级作用域范围
10 | 2、`const` 在声明时必须被赋值, 而且只读,不能重新赋值
11 | 3、`let` 和 `const` 关键词声明的变量不具备变量提升(hoisting)特性
12 | 4、用块级作用域代替`IIFES`(创造一个内部的作用域)
13 | ```javascript
14 | //ES6
15 | const a = 1
16 | let b = 'foo'
17 | // a = 2 // Uncomment me!, "a" is read-only
18 | // b = 'bar'
19 | if (true) {
20 | const a = 3;//此a和上面的a是两个不同变量
21 | console.log(a); // 3
22 | }
23 | console.log(a); // 1
24 |
25 | for(let j = 0; j < 10; j++){
26 |
27 | }
28 | console.log(j); // ReferenceError: j is not defined
29 |
30 | const c;//unknown: Unexpected token
31 | ```
32 | #### 二、对象和数组解构(Destructuring)
33 | ```javascript
34 | let x = 2;
35 | let y = 3;
36 | [x, y] = [y, x]; // x is now 3, and y is now 2
37 |
38 | function foo() {
39 | return [1,2,3];
40 | }
41 | let arr = foo(); // [1,2,3]
42 |
43 | let [ , b, c] = foo();
44 | console.log(b, c); //2 3
45 |
46 | function bar() {
47 | return {
48 | x: 4,
49 | y: 5,
50 | z: 6
51 | };
52 | }
53 | let {x:x, y: y, z: z} = bar();
54 | //let {x, y, z} = bar(); //或者省略写
55 | console.log(x, y, z); // 4 5 6
56 |
57 |
58 | let doSomething = function() {
59 | return {
60 | firstName: "Charles",
61 | lastName: "Bronson",
62 | handles: {
63 | twitter: "@NoDice",
64 | facebook: "bronson69"
65 | }
66 | };
67 | };
68 |
69 | let { firstName, lastName, handles:{twitter} } = doSomething();
70 |
71 | console.log(twitter);//@NoDice
72 | ```
73 | The old way when working with a function:
74 | ```javascript
75 | let doSomething = function(url, config){
76 | return config.data; // "test"
77 | };
78 |
79 | var config = { data: "test", cache: false }
80 | let result = doSomething("api/test", config);
81 | ```
82 | 解构参数新方式
83 | ```javascript
84 | let doSomething = function(url, {data, cache}){
85 | return data; // `test` comes directly from the `data` property
86 | };
87 |
88 | let result = doSomething("api/test", {data: "test", cache: false});
89 | ```
90 | **对象解构**
91 | ```javascript
92 | let luke = { occupation: 'jedi', father: 'anakin' };
93 | let {occupation, father} = luke;
94 |
95 | console.log(occupation); // 'jedi'
96 | console.log(father); // 'anakin'
97 | ```
98 | #### 三、参数默认值
99 | 无参的老处理方式如下
100 | ```javascript
101 | var doSomething = function(name){
102 | return name || "Taylor";
103 | };
104 | var a = doSomething();//或传入0、""、null、undefined都等于"Taylor"
105 | console.log(a);
106 | ```
107 | ES6新方式
108 | ```javascript
109 | var doSomething = function(name="Taylor"){
110 | return name;
111 | };
112 | ```
113 | 【注意】ES6和原设置默认的区别如下
114 | ```javascript
115 | let result = doSomething(); // "Taylor"
116 | let result = doSomething(""); // Undefined
117 | let result = doSomething(undefined); // "Taylor"
118 | let result = doSomething("Colleen"); // "Colleen"
119 | let result = doSomething(null); // null
120 | ```
121 | Combining Concepts:
122 | ```javascript
123 | let doSomething = function(a = 1, b = 2, c = 3){
124 | return [a, b, c];
125 | };
126 |
127 | let [a,b,c] = doSomething(5, undefined); // a = 5, b = 2, c = 3
128 | ```
129 | 与解构(destructuring)的例子:
130 | ```javascript
131 | let doSomething = function(url, {data = "Taylor", cache = true}){
132 | return data;
133 | };
134 |
135 | let result = doSomething("api/test", { cache: false }); // "Taylor" is returned (and `cache` is `false` inside the function)
136 | ```
137 | #### 四、Spread展开 / Rest剩余 操作符
138 | Spread / Rest 操作符指的是 ...,具体是 Spread 还是 Rest 需要看上下文语境。
139 | 1、当被用于迭代器中时,它是一个 Spread 操作符:
140 | ```javascript
141 | function foo(x,y,z) {
142 | console.log(x,y,z);
143 | }
144 | let arr = [1,2,3];
145 | foo(...arr); // 1 2 3 【数组展开了有木有!!!】
146 |
147 | var a = [4, 5, 6];
148 | var b = [1, 2, 3, ...a, 7, 8, 9]; //b is now [1, 2, 3, 4, 5, 6, 7, 8, 9]
149 |
150 | let num1 = [1, 2, 3];
151 | let num2 = [0, ...num1];
152 | console.log(num1); //[1, 2, 3];
153 | console.log(...num1); //1 2 3
154 | console.log(num2); //[0, 1, 2, 3];
155 | ```
156 | 2、当被用于函数传参时,是一个 Rest 操作符:
157 | ```javascript
158 | function foo(name, ...args) {
159 | console.log(args); // [1, 2, 3, 4, 5]
160 | console.log(...args); // 1 2 3 4 5
161 | }
162 | var a = foo("Taylor", 1, 2, 3, 4, 5);
163 | ```
164 | #### 五、模板语法和分隔符
165 | ${ ... } 用来渲染一个变量,
166 | ```javascript
167 | let category = "music";
168 | let id = 2112;
169 | //` 作为分隔符
170 | let url= `http://apiserver/${category}/${id}`;
171 |
172 | //模版字符串 可以支持换行并且不需要额外的处理:
173 | let text = ( `cat
174 | dog
175 | nickelodeon`
176 | );
177 | ```
178 | **带标签的模板字符串**
179 | ```javascript
180 | let one = '1', two = '2';
181 | funcNum = (strings, ...values) => {
182 | console.log(strings);
183 | console.log(values);
184 | //输出字符串
185 | let resultStr = '';
186 | for(let i = 0; i < values.length; i++) {
187 | resultStr += strings[i];
188 | resultStr += values[i];
189 | }
190 | resultStr += strings[strings.length - 1];
191 | console.log(resultStr);
192 | return resultStr;
193 |
194 |
195 | }
196 | let nums = funcNum`数字有\n ${one} 与 ${two} !`;
197 | console.log(nums);
198 | ```
199 | 打印输出如下
200 | ```
201 | //1、console.log(strings);
202 | ["数字有
203 | ", " 与 ", " !"]
204 | //2、console.log(values);
205 | ["1", "2"]
206 | //3、console.log(resultStr);
207 | "数字有
208 | 1 与 2 !"
209 | //4、console.log(nums);
210 | "数字有
211 | 1 与 2 !"
212 | ```
213 |
--------------------------------------------------------------------------------
/00、es6-notes/03-FunctionalJS函数.md:
--------------------------------------------------------------------------------
1 | * 一、箭头函数=>
2 | * 二、箭头作为异步callback
3 | * 三、迭代器(Iterators)
4 | * 四、生成器(Generators)
5 |
6 | #### 一、箭头函数(Arrow Functions)
7 | [《箭头函数》链接](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
8 | 1、基础语法
9 | ```javascript
10 | (param1, param2, …, paramN) => { statements }
11 |
12 | (param1, param2, …, paramN) => expression
13 | // 相当于: => { return expression; }
14 |
15 | // 如果只有一个参数,圆括号是可选的:
16 | (singleParam) => { statements }
17 | singleParam => { statements }
18 |
19 | // 无参数的函数需要使用圆括号:
20 | () => { statements }
21 | ```
22 | 2、高级语法
23 | ```javascript
24 | // 返回对象字面量时应当用圆括号将其包起来:
25 | params => ({foo: bar})
26 |
27 | // 支持 Rest parameters 和 default parameters:
28 | (param1, param2, ...rest) => { statements }
29 | (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
30 |
31 | // Destructuring within the parameter list is also supported
32 | var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
33 | f(); // 6
34 | ```
35 | 3、更短的函数
36 | ```javascript
37 | var arr = [
38 | "Hydrogen",
39 | "Helium",
40 | "Lithium",
41 | "Beryllium"
42 | ];
43 | var a2 = arr.map(function(a){ return a.length });
44 | //更短的函数写法
45 | var a3 = arr.map( s => s.length );//[8, 6, 7, 10]
46 | ```
47 | 4、箭头函数中`this`总是绑定指向对象自身
48 | 解决了ES5中需要给回调函数维护一个词法作用域的上下文this(var that = this;)
49 | ```javascript
50 | //ES5中
51 | var age = 100;
52 | function Person() {
53 | this.age = 0;
54 |
55 | setInterval(function growUp() {
56 | // 在非严格模式下,growUp() 函数的 this 指向 window 对象
57 | this.age++;
58 | console.log(this.age);//101,102...
59 | }, 1000);
60 | }
61 | var person = new Person();
62 |
63 | //ES6实现
64 | function Person(){
65 | this.age = 0;
66 |
67 | setInterval(() => {
68 | // |this| 指向 person 对象
69 | this.age++;
70 | console.log(this.age); //1,2...
71 | }, 1000);
72 | }
73 | var person = new Person();
74 | ```
75 | 5、使用 call 或 apply 调用
76 | 由于 this 已经在词法层面完成了bound,通过 call() 或 apply() 方法调用一个函数时,只是传入了参数而已,对 this 并没有什么影响:
77 | ```javascript
78 | var adder = {
79 | base : 1,
80 |
81 | add : function(a) {
82 | var f = v => v + this.base;
83 | return f(a);
84 | },
85 |
86 | addThruCall: function(a) {
87 | var f = v => v + this.base;
88 | var b = {
89 | base : 2
90 | };
91 |
92 | return f.call(b, a);
93 | }
94 | };
95 |
96 | console.log(adder.add(1)); // 输出 2
97 | console.log(adder.addThruCall(1)); // 仍然输出 2(而不是3)
98 | ```
99 | 6、arguments 的词法
100 | 箭头函数不会在其内部暴露出 arguments 对象: arguments.length, arguments[0], arguments[1] 等等,都不会指向箭头函数的 arguments,而是指向了箭头函数所在作用域的一个名为 arguments 的值(如果有的话,否则,就是 undefined)
101 | ```javascript
102 | var arguments = 42;
103 | var arr = () => arguments;
104 |
105 | arr(); // 42
106 |
107 | function foo() { //foo 的arguments
108 | var f = () => arguments[0]; // foo's implicit arguments binding
109 | return f(2);
110 | }
111 |
112 | foo(1); // 1
113 | ```
114 | 箭头函数没有自己的 arguments 对象,不过在大多数情形下,rest参数可以给出一个解决方案:
115 | ```javascript
116 | function foo() {
117 | var f = (...args) => args[0];
118 | return f(2);
119 | }
120 |
121 | foo(1); // 2
122 | ```
123 | **更多示例**
124 | ```javascript
125 | // 一个空箭头函数,返回 undefined
126 | let empty = () => {};
127 |
128 | (() => "foobar")() // 返回 "foobar"
129 |
130 | var simple = a => a > 15 ? 15 : a;
131 | simple(16); // 15
132 | simple(10); // 10
133 |
134 | let max = (a, b) => a > b ? a : b;
135 |
136 | // Easy array filtering, mapping, ...
137 |
138 | var arr = [5, 6, 13, 0, 1, 18, 23];
139 | var sum = arr.reduce((a, b) => a + b); // 66
140 | var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
141 | var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]
142 | ```
143 |
144 | #### 二、箭头作为异步callback
145 | ```javascript
146 | this.name = "Taylor";
147 |
148 | ajaxCall("aUrl", (response) => {
149 | this.name = response.data;
150 | });
151 | ```
152 | #### 三、迭代器(Iterators)
153 | 迭代器允许每次访问数据集合的一个元素,当指针指向数据集合最后一个元素是,迭代器便会退出。它提供了 next() 函数来遍历一个序列,这个方法返回一个包含 done 和 value 属性的对象。
154 | ES6 中可以通过 Symbol.iterator 给对象设置默认的遍历器,无论什么时候对象需要被遍历,执行它的 @@iterator 方法便可以返回一个用于获取值的迭代器。
155 | 数组默认就是一个迭代器:
156 | ```javascript
157 | var arr = [11,12,13];
158 | var itr = arr[Symbol.iterator]();
159 |
160 | itr.next(); // { value: 11, done: false }
161 | itr.next(); // { value: 12, done: false }
162 | itr.next(); // { value: 13, done: false }
163 |
164 | itr.next(); // { value: undefined, done: true }
165 | ```
166 | 你可以通过 [Symbol.iterator]() 自定义一个对象的迭代器。
167 | #### 四、生成器(Generators)
168 | 就像 Promises 可以帮我们避免回调地狱,Generators 可以帮助我们让代码风格更整洁-
169 | -用同步的代码风格来写异步代码,它本质上是一个可以暂停计算并且可以随后返回表达式的值的函数。
170 | Generator 函数是 ES6 的新特性,它允许一个函数返回的可遍历对象生成多个值。
171 | 在使用中你会看到 * 语法和一个新的关键词 yield:
172 | ```javascript
173 | function* infiniteNumbers() {
174 | var n = 1;
175 | while (true){
176 | yield n++;
177 | }
178 | }
179 | var numbers = infiniteNumbers(); // returns an iterable object
180 |
181 | numbers.next(); // { value: 1, done: false }
182 | numbers.next(); // { value: 2, done: false }
183 | numbers.next(); // { value: 3, done: false }
184 | ```
185 | 每次执行 yield 时,返回的值变为迭代器的下一个值。
186 | ```javascript
187 | let numbers = function*(start, end) {
188 | for(let i = start; i <= end; i++) {
189 | console.log(i);
190 | yield i;
191 | }
192 | };
193 | //使用"for of" with a Generator
194 | let sum = 0;
195 | for(let n of numbers(1,5)){
196 | sum += n;
197 | console.log("next");
198 | }
199 |
200 | sum; // 15
201 | ```
202 | 可以利用 Generators 来用同步的方式来写异步操作:
203 | ```javascript
204 | // Hiding asynchronousity with Generators
205 | function getRequest(url) {
206 | getJSON(url, function(response) {
207 | generator.next(response);
208 | });
209 | }
210 | ```
211 | 这里的 generator 函数将会返回需要的数据:
212 | ```javascript
213 | function* getData() {
214 | var entry1 = yield getRequest('http://some_api/item1');
215 | var data1 = JSON.parse(entry1);
216 | var entry2 = yield getRequest('http://some_api/item2');
217 | var data2 = JSON.parse(entry2);
218 | }
219 | ```
220 | 通过 yield,我们可以保证 entry1 有 data1 中我们需要解析并储存的数据。
221 | 虽然我们可以利用 Generators 来用同步的方式来写异步操作,但是确认错误的传播变得不再清晰,我们可以在 Generators 中加上 Promise:
222 | ```javascript
223 | function request(url) {
224 | return new Promise((resolve, reject) => {
225 | getJSON(url, resolve);
226 | });
227 | }
228 | ```
229 | 然后我们写一个函数逐步调用 next 并且利用 request 方法产生一个 Promise:
230 | ```javascript
231 | function iterateGenerator(gen) {
232 | var generator = gen();
233 | (function iterate(val) {
234 | var ret = generator.next();
235 | if(!ret.done) {
236 | ret.value.then(iterate);
237 | }
238 | })();
239 | }
240 | ```
241 | 在 Generators 中加上 Promise 之后我们可以更清晰的使用 Promise 中的 .catch 和 reject来捕捉错误,让我们使用新的 Generator,和之前的还是蛮相似的:
242 | ```javascript
243 | iterateGenerator(function* getData() {
244 | var entry1 = yield request('http://some_api/item1');
245 | var data1 = JSON.parse(entry1);
246 | var entry2 = yield request('http://some_api/item2');
247 | var data2 = JSON.parse(entry2);
248 | });
249 | ```
250 |
--------------------------------------------------------------------------------