ES6(四) Class类、模块

1.Class类

1.1基本用法

类定义

// 匿名类
let Example = class {
    constructor(a) {
        this.a = a;
    }
}
// 命名类
let Example = class Example {
    constructor(a) {
        this.a = a;
    }
}

类表达式可以为匿名或命名。

类声明

class Example {
    constructor(a) {
        this.a = a;
    }
}

在这里插入图片描述
注意不可以重复声明否则会报VM88:1 Uncaught SyntaxError: Identifier ‘Example’ has already been declared错误。

类的主体

属性
prototype:覆盖方法 / 初始化时添加方法。

Example.prototype={
//methods
}

//添加方法
Object.assign(Example.prototype,{
//methods
})

静态属性:class 本身的属性,即直接定义在类内部的属性( Class.propname ),不需要实例化。 ES6 中规定,Class 内部只有静态方法,没有静态属性。

class Example {
// 新提案
    static a = 2;
}
// 目前可行写法
Example.b = 2;

公共属性

class Example{}
Example.prototype.a = 2;

实例属性:定义在实例对象( this )上的属性。

class Example {
    a = 2;
    constructor () {
        console.log(this.a);
    }
}

方法

constructor 方法是类的默认方法,创建类的实例化对象时被调用。

class Example{
    constructor(){
      console.log('我是YY');
    }
}
new Example(); // 我是YY

静态方法

class Example{
    static sum(a, b) {
        console.log(a+b);
    }
}
Example.sum(1, 2)

原型方法

class Example {
    sum(a, b) {
        console.log(a + b);
    }
}
let exam = new Example();
exam.sum(1, 2); // 3

实例方法

class Example {
    constructor() {
        this.sum = (a, b) => {
            console.log(a + b);
        }
    }
}

类的实例化

class Example {}
 
let exam1 = Example(); 
// Class constructor Example cannot be invoked without 'new'

class 的实例化必须通过 new 关键字,否则会报错。

实例化对象

class Example {
    constructor(a, b) {
        this.a = a;
        this.b = b;
        console.log('Example');
    }
    sum() {
        return this.a + this.b;
    }
}
let exam1 = new Example(2, 1);
let exam2 = new Example(3, 1);
console.log(exam1._proto_ == exam2._proto_); // true
 
exam1._proto_.sub = function() {
    return this.a - this.b;
}
console.log(exam1.sub()); // 1
console.log(exam2.sub()); // 2

1.2封装与继承

getter / setter

class Example{
    constructor(a, b) {
        this.a = a; // 实例化时调用 set 方法
        this.b = b;
    }
    get a(){
        console.log('getter');
        return this.a;
    }
    set a(a){
        console.log('setter');
        this.a = a; // 自身递归调用
    }
}

在这里插入图片描述
getter 与 setter 必须同级出现,否则会直接输出undefined。

extends

class Child extends Father { ... }

通过 extends 实现类的继承。

super
在这里插入图片描述
子类 constructor 方法中必须有 super ,且必须出现在 this 之前,否则会报Uncaught ReferenceError: Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor错误。

注意要点

var Father = {
    // ...
}
class Child extends Father {
     // ...
}
// Uncaught TypeError: Class extends value #<Object> is not a constructor or null
 
// 解决方案
Object.setPrototypeOf(Child.prototype, Father);

不可继承常规对象。

2.模块

2.1export 与 import

export 命令可以出现在模块的任何位置,但必需处于模块顶层。
import 命令会提升到整个模块的头部,首先执行。

/*-----export [module1.js]-----*/
let myName = "Tom";
let myAge = 20;
let myfn = function(){
    return "My name is" + myName + "! I'm '" + myAge + "years old."
}
let myClass =  class myClass {
    static a = "yeah!";
}
export { myName, myAge, myfn, myClass }
 
/*-----import [module2.js]-----*/
import { myName, myAge, myfn, myClass } from "./module1.js";
console.log(myfn());// My name is Tom! I'm 20 years old.
console.log(myAge);// 20
console.log(myName);// Tom
console.log(myClass.a );// yeah!

as 的用法

/*-----export [module1.js]-----*/
let myName = "Jerry";
export { myName as exportName  }

/*-----import [module2.js]-----*/
import { exportName  as name1 } from "./module1.js";
console.log(name1);// Jerry

export 命令导出的接口名称,须和模块内部的变量有一一对应关系。
导入的变量名,须和导出的接口名称相同,即顺序可以不一致。

export default 命令

var a = "My name is Tom!";
export default a; // 仅有一个
export default var c = "error"; 
// error,default 已经是对应的导出变量,不能跟着变量声明语句
 export default function(){
 }	
 
import b from "./module1.js"; // 不需要加{}, 使用任意变量接收

在一个文件或模块中,export、import 可以有多个,export default 仅有一个。
export default 中的 default 是对应的导出接口变量。
通过 export 方式导出,在导入时要加{ },export default 则不需要。
export default 向外暴露的成员,可以使用任意变量来接收。

2.2复合使用

export 与 import 可以在同一模块使用,使用特点:
可以将导出接口改名,包括 default。
复合使用 export 与 import ,也可以导出全部,当前模块导出的接口会覆盖继承导出的。

export { foo, bar } from "methods";

// 约等于下面两段语句,不过上面导入导出方式该模块没有导入 foo 与 bar
import { foo, bar } from "methods";
export { foo, bar };
 
/* ------- 特点 1 --------*/
// 普通改名
export { foo as bar } from "methods";
// 将 foo 转导成 default
export { foo as default } from "methods";
// 将 default 转导成 foo
export { default as foo } from "methods";
 
/* ------- 特点 2 --------*/
export * from "methods";

模块的好处
1.减少命名冲突
2.避免引入时的层层依赖
3.可以提升执行效率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值