资讯专栏INFORMATION COLUMN

React&ES6

jeffrey_up / 927人阅读

摘要:在中必须调用方法,因为子类没有自己的对象,而是继承父类的对象,然后对其进行加工而就代表了父类的构造函数。虽然代表了父类的构造函数,但是返回的是子类的实例,即内部的指的是,因此在这里相当于。要求,子类的构造函数必须执行一次函数,否则会报错。

1.class
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的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

  this.input = input} />//input为获取的节点
4.react组件可内嵌组件或者节点原理
嵌套的结构在组件内部都可以通过 props.children 获取到
class Card extends Component {
  render () {
    return (
      
{this.props.children[0]}
{this.props.children[1]}
) } } ReactDOM.render(
children[0]
children[1]
, 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

2
constructor(props) {
        super(props);
        this.state = {

        };
        this.handleClick=this.handleClick.bind(this)
    }
3
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 
    }
  }
  return NewComponent
}
import wrapWithLoadData from "./wrapWithLoadData"

class InputWithUserName extends Component {
  render () {
    return 
  }
}

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
13.Decorator修饰器应用//@connect原理
修饰器是一个对类进行处理的函数。修饰器函数的第一个参数,就是所要修饰的目标类。@是语法糖

1.类的修饰

function decorator(target) {
  target.isTestable = true;
}
@decorator
class A {}

// 等同于
class A {}
A = decorator(A) || A;

A.isTestable//true

2.修饰器带参数

function testable(isTestable) {
  return function(target) {
    target.isTestable = isTestable;
  }
}

@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true

3.与redux库结合

class MyReactComponent extends React.Component {}
export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
//connect(mapStateToProps, mapDispatchToProps)返回一个函数
//加上()即(MyReactComponent),再次执行函数,传入一个组件返回一个被修饰的组件
==
@connect(mapStateToProps, mapDispatchToProps)//将props导入到被修饰的组件上去
export default class MyReactComponent extends React.Component {}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/53637.html

相关文章

  • 马上开始写 react & ES6 --- 基于gulp 和 Babel 的脚手架

    摘要:我对很有兴趣,但是我发现想写不容易。于是我马上动手,有了这个,本意是自己用,现在也推荐给大家,也希望大家积极指出不足,提出建议,当然如果有更好的方案,也可以推荐给我。特点使用了,这样可以用来书写代码。 我对 react 很有兴趣,但是我发现想写 react 不容易。 我需要在开始写代码之前做很多准备工作,我需要编译jsx文件,引入react等等,而最新的react示例,有鼓励ES6来书...

    Lemon_95 评论0 收藏0
  • react: 组件初识 && 生命周期 && 相关说明

    react组件 参考:https://facebook.github.io/re... react的组件是其核心思想部分,react允许将整个ui设计分割称为独立的、可复用的隔离模块,react的组件是一个抽象的类,直接使用reacy.component是没有很大意义的,所以一般使用的方法就是定义一个 class 来继承这个component,并且需要实现方法 render();就像下面一样: ...

    jokester 评论0 收藏0
  • react:组件初识 && 生命周期 && tips

    react组件 参考:https://facebook.github.io/re... react的组件是其核心思想部分,react允许将整个ui设计分割称为独立的、可复用的隔离模块,react的组件是一个抽象的类,直接使用reacy.component是没有很大意义的,所以一般使用的方法就是定义一个 class 来继承这个component,并且需要实现方法 render();就像下面一样: ...

    miqt 评论0 收藏0
  • vscode插件&主题

    摘要:插件记录和主题建议自动闭合标签双标签更改时自动同步代码美化工具给括号着色使之更易识别的中文语言包颜色选择工具吸血鬼主题主题日志支持支持包提示路径补全语法支持语法支持支持通过同步插件插件文件图标插件在中调试页面更新添加设置效果 vscode插件记录和主题建议 Auto Close Tag + 自动闭合标签 Auto Rename Tag + 双标签更改时自动同步 Beautify ...

    孙吉亮 评论0 收藏0

发表评论

0条评论

jeffrey_up

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<