内容简介:ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。1.类的所有方法都定义在类的prototype属性上面2.Point.prototype.constructor === Point // true
1.class
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
特点
1.类的所有方法都定义在类的prototype属性上面
class Point { constructor() { // ... } } == Point.prototype = { constructor() {}, };
2.Point.prototype.constructor === Point // true
3.定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了
4.类不存在变量提升(hoist),这一点与 ES5 完全不同。
5.类的方法内部如果含有this,它默认指向类的实例
6.如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静 态方法”。
7.写法
ES5写法
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; var p = new Point(1, 2);
ES6
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
2.constructor( )——构造方法
这是ES6对类的默认方法,通过 new 命令生成对象实例时自动调用该方法。并且,该方法是类中必须有的,如果没有显示定义,则会默认添加空的constructor( )方法。
1.constructor方法默认返回实例对象(即this)
class Point { constructor(x, y) { this.x = x; this.y = y; } } point.hasOwnProperty('x') // true
2.super( ) ——继承
在class方法中,继承是使用 extends 关键字来实现的。子类 必须 在 constructor( )调用 super( )方法,否则新建实例时会报错。 在 constructor 中必须调用 super 方法,因为子类没有自己的 this 对象,而是继承父类的 this 对象 ,然后对其进行加工,而 super 就代表了父类的构造函数。super 虽然代表了父类 A 的构造函数, 但是返回的是子类 B 的实例,即 super 内部的 this 指的是 B,因此 super() 在这里相当于 A.prototype.constructor.call(this, props)。 class A {} class B extends A { constructor() { super(); // ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。 } }
3.如果你在constructor中要使用this.props,就必须给super加参数:super(props);
3.ref 和 React.js 中的 DOM 操作
顺带一提的是,其实可以给组件标签也加上 ref
<input ref={(input) => this.input = input} />//input为获取的节点
4.react组件可内嵌组件或者节点原理
嵌套的结构在组件内部都可以通过 props.children 获取到 class Card extends Component { render () { return ( <div className='Card'> <div className='0'> {this.props.children[0]} </div> <div className='1'> {this.props.children[1]} </div> </div> ) } } ReactDOM.render( <Card> <div>children[0]</div> <div>children[1]</div> </Card>, document.getElementById('root') )
5.默认配置 defaultProps&&给组件的配置参数加上类型验证
class LikeButton extends Component { static defaultProps = { likedText: '取消', unlikedText: '点赞' } static propTypes = { comment: PropTypes.object//const { comment } = this.props } static propTypes = { comment: PropTypes.object.isRequired } }
6.react中bind(this)的理解
bind返回值是由指定的this值和初始化参数改造的原函数拷贝
在JSX中传递的事件不是一个字符串,而是一个函数(如:onClick={this.handleClick}),此时onClick即是中间变量,所以处理函数中的this指向会丢失。解决这个问题就是给调用函数时bind(this),从而使得无论事件处理函数如何传递,this指向都是当前实例化对象。
当然,如果不想使用bind(this),我们可以在声明函数时使用箭头函数将函数内容返回给一个变量,并在调用时直接使用this.变量名即可
1 <button onClick={this.handleClick.bind(this)}>有bind点击一下</button> 2 constructor(props) { super(props); this.state = { }; this.handleClick=this.handleClick.bind(this) } 3 <button onClick={()=>{this.handleClick()}>
7.高阶组件
高阶组件是一个函数(而不是组件),它接受一个组件作为参数,返回一个新的组件。这个新的组件会使用你传给它的组件作为子组件
import React, { Component } from 'react' export default (WrappedComponent, name) => { class NewComponent extends Component { constructor () { super() this.state = { data: null } } componentWillMount () { let data = localStorage.getItem(name) this.setState({ data }) } render () { return <WrappedComponent data={this.state.data} /> } } return NewComponent }
import wrapWithLoadData from './wrapWithLoadData' class InputWithUserName extends Component { render () { return <input value={this.props.data} /> } } InputWithUserName = wrapWithLoadData(InputWithUserName, 'username') export default InputWithUserName
8.export&&import
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量
1.export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系
2.export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值
3.注意输出时{}的使用表明其是一个接口,不用则为值会报错
//export var year = 1958; var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export {firstName, lastName, year}; ---------- // 报错 export 1; // 报错 var m = 1; export m; ---------- // 写法一 export var m = 1; // 写法二 var m = 1; export {m}; // 写法三 var n = 1; export {n as m}; //函数 function f() {} export {f};
4.import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同
5.如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名
6.import命令输入的变量都是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写
接口
7.注意,import命令具有提升效果,会提升到整个模块的头部,首先执行
8.import是静态执行,所以不能使用表达式和变量
import { lastName as surname } from './profile.js'; import {myMethod} from 'util';//util是模块文件名,必须通过配置,告诉引擎怎么取到这个模块 import 'lodash';//import语句会执行所加载的模块
9.模块的整体加载
除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。
// circle.js export function area(radius) { return Math.PI * radius * radius; } export function circumference(radius) { return 2 * Math.PI * radius; }
import * as circle from './circle'; console.log('圆面积:' + circle.area(4)); console.log('圆周长:' + circle.circumference(14));
10.export default命令,为模块指定默认输出
// export-default.js export default function () { console.log('foo'); } // import-default.js import customName from './export-default'; customName(); // 'foo'
1.使用export default时,对应的import语句不需要使用大括号
// 第一组 export default function crc32() { // 输出 // ... } import crc32 from 'crc32'; // 输入 // 第二组 export function crc32() { // 输出 // ... }; import {crc32} from 'crc32'; // 输入 //结合使用 import _, { each, forEach } from 'lodash';
2.export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句
// 正确 export var a = 1; // 正确 var a = 1; export default a; // 错误 export default var a = 1;
11.解构赋值
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子
let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3 let [ , , third] = ["foo", "bar", "baz"]; third // "baz" let [x, , y] = [1, 2, 3]; x // 1 y // 3 let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] let [x, y, ...z] = ['a']; x // "a" y // undefined z // []
1.如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错
// 报错 let [foo] = 1; let [foo] = false; let [foo] = NaN;
2.解构赋值允许指定默认值
let [foo = true] = []; foo // true let [x, y = 'b'] = ['a']; // x='a', y='b' let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
3.解构不仅可以用于数组,还可以用于对象
//简易模型 let { bar, foo } = { foo: "aaa", bar: "bbb" }; foo // "aaa" bar // "bbb" let { baz } = { foo: "aaa", bar: "bbb" }; baz // undefined
//基本模型 var robotA = { name: "Bender" }; var robotB = { name: "Flexo" }; var { name: nameA } = robotA; var { name: nameB } = robotB; nameA//"Bender" nameB//"Flexo"
//多重解构 const node = { loc: { start: { line: 1, column: 5 } } }; let { loc, loc: { start }, loc: { start: { line }} } = node; line // 1 loc // Object {start: Object} start // Object {line: 1, column: 5}
//默认值 var {x, y = 5} = {x: 1}; x // 1 y // 5 var { message: msg = "Something went wrong" } = {};
//JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误 //只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题 let x; ({x} = {x: 1});
//字符解构 const [a, b, c, d, e] = 'hello'; a // "h" b // "e" c // "l" d // "l" e // "o"
12箭头函数
箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值。这就意味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的 this。
没有 arguments
不能通过 new 关键字调用
没有原型
没有 super
格式1:多个参数 (param1, param2, …, paramN) => { statements } // statements应该有return 语句 (param1, param2, …, paramN) => expression //相当于 return expression 格式2:一个参数 (singleParam) => { statements } singleParam => { statements } //可以去掉括号 格式3:没有参数 () => { statements } 格式4:返回对象 params => ({foo: bar}) 格式5:支持扩展符号 (param1, param2, ...rest) => { statements } 格式6:支持默认值 (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } 格式7:支持解构赋值 var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
以上所述就是小编给大家介绍的《React&ES6》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- React 20 - 不使用ES6(React Without ES6)
- React&ES6
- 基于React Context Api 和 Es6 Proxy的状态管理
- 前端开发规范手册(命名、HTML、CSS、JS、ES6、React)
- ES6的class本质和react中需要使用bind(this)的原因
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
微信小程序入门指南
知晓程序 / 电子工业出版社 / 2017-6-1 / 49
《知晓程序:微信小程序入门指南》是一本分析小程序生态、解读小程序产品设计与开发的入门图书。全书共 9 章,全面讲解了小程序的基本知识、大家如何看待小程序、小程序对行业的影响、小程序对开发者的影响、小程序对用户的影响、开发小程序需要的准备工作等内容,并深入解读了小程序的官方文档。 读者在阅读《知晓程序:微信小程序入门指南》之后可以清楚小程序与订阅号、服务号的区别,了解小程序适用的场景,认识小程......一起来看看 《微信小程序入门指南》 这本书的介绍吧!