内容简介: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)的原因
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ordering Disorder
Khoi Vinh / New Riders Press / 2010-12-03 / USD 29.99
The grid has long been an invaluable tool for creating order out of chaos for designers of all kinds—from city planners to architects to typesetters and graphic artists. In recent years, web designers......一起来看看 《Ordering Disorder》 这本书的介绍吧!