Class 类

Class 是什么

  1. 认识 Class
    类可以看做是对象的模板,用一个类可以创建出许多不同的对象
  2. Class 的基本用法
    类名一般首字母大写
class Person {
	// 实例化时执行构造方法,所以必须有构造方法,但可以不写出来
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}
	// 一般在构造方法中定义属性,方法不在构造方法中定义
	// 各实例共享的方法
	speak() {
		console.log('speak');
	}
}
const zs = new Person('ZS', 18);
const ls = new Person('LS', 28);
console.log(zs.name);
console.log(zs.age);
zs.speak();
console.log(ls.name);
console.log(ls.age);
ls.speak();
  1. Class 与构造函数
class Person {
	constructor (name, age) {
		this.name = name;
		this.age = age;
	}
	speak() {
		console.log('speak');
	}
}

function Person (name, age) {
	this.name = name;
	this.age = age;
}
Person.prototype.speak = function () {}

Class 的两种定义形式

  1. 声明形式
class Person {
	constructor() {}
	speak() {}
}
  1. 表达式形式
const Person = class {
	constructor() {
		console.log('constructor');
	}
	speak() {}
}

立即执行的类

new (class {
	constructor() {
		console.log('constructor');
	}
})();

实例方法、静态方法和静态属性

  1. 实例属性
    方法就是值为函数的特殊属性
class Person {
	age = 0;
	sex = 'male';
	getSex = function () {
		return this.sex;
	};
	constructor(name, sex) {
		this.name = name;
		this.sex = sex;
	}
	speak() {
		console.log('speak');
	}
}
  1. 静态方法
    类的方法
class Person {
	constructor(name) {
		this.name = name;
	}
	speak() {
		console.log('speak');
		// 指向实例
		console.log(this);
	}
	static speak () {
		console.log('人类会说话');
		// 指向类
		console.log(this);
	}
}
// 静态方法另一种写法(不推荐使用)
Person.speak = function () {
	console.log('人类可以说话');
	console.log(this);
}
const p = new Person('Tom');
p.speak();

Person.speak();
  1. 静态属性
class Person {
	constructor(name) {
		this.name = name;
	}
	// 不要这么写,目前只是提案,有兼容性问题
	static version = '1.0';
	// 变通的方法
	static getVersion() {
		return '1.0';
	}
}
// 不建议这么写,违背封装原则
Person.version = '1.0';

私有属性和方法

  1. 为什么需要私有属性和方法
    一般情况下,类的属性和方法都是公开的
    公有的属性和方法可以被外界修改,造成意想不到的错误
  2. 模拟私有属性的方法
    2.1 _开头表示私有
    2.2 将私有属性和方法移出来
(function () {
  let name = '';
  class Person {
    constructor(username) {
      name = username;
    }

    getName() {
      return name;
    }
  }
  window.Person = Person;
})();
(function () {
  const p = new Person('Tom');
  console.log(p.getName());
})();

extends

class Person {
	constructor(name, sex) {
		this.name = name;
		this.sex = sex;
		this.say = function () {
			console.log('say');
		}
	}
	speak() {
		console.log('speak');
	}
	static speak() {
		console.log('static speak');
	}
}
Person.version = '1.0';

class Programmer extends Person {
	constructor(name, sex) {
		super(name, sex);
	}
}

const zs = new Programmer('zs', '男');
console.log(zs.name);
console.log(zs.sex);
zs.say();
zs.speak();
Programmer.speak();
console.log(Programmer.version);
  1. 改写继承的属性或方法
    同名覆盖
    this 操作不能放在 super 前面
class Person {
	constructor(name, sex) {
		this.name = name;
		this.sex = sex;
		this.say = function () {
			console.log('say');
		}
	}
	speak() {
		console.log('speak');
	}
	static speak() {
		console.log('static speak');
	}
}
Person.version = '1.0';

class Programmer extends Person {
	constructor(name, sex, feature) {
		// this 操作不能放在 super 前面
		super(name, sex);
		this.feature = feature;
	}
	speak() {
		console.log('Programmer speak');
	}
	static speak() {
		console.log('Programmer static speak');
	}
}
Programmer.version = '2.0';

const zs = new Programmer('zs', '男', 'java');
console.log(zs.name);
console.log(zs.sex);
zs.say();
zs.speak();
Programmer.speak();
console.log(Programmer.version);

super

  1. 作为函数调用
    代表父类的构造方法,只能用在子类的构造方法中,用在其他地方就会报错
    super 虽然代表了父类的构造方法,但是内部的 this 指向子类的实例
class Person {
	constructor(name) {
		this.name = name;
		console.log(this);
	}
}
class Programmer extends Person {
	constructor(name, sex) {
		super(name, sex);
	}
}
new Programmer();
  1. 作为对象使用
    2.1 在构造方法中使用或一般方法中使用
    super 代表父类的原型 Person.prototype
    所以定义在父类实例上的方法或属性,是无法通过 super 调用的
    通过 super 调用父类的方法时,方法内部的 this 指向当前的子类实例
class Person {
	constructor(name) {
		this.name = name;
		console.log(this);
	}
	speak() {
		console.log('speak');
	}
}
class Programmer {
	constructor(name) {
		super(name);
		super.speak();
	}
	speak () {
		super.speak();
		console.log('Programmer speak');
	}
}
new Programmer('Tom');

2.2 在静态方法中使用
指向父类,而不是父类的原型对象
通过 super 调用父类的方法时,方法内部的 this 指向当前的子类,而不是子类的实例

class Person {
	constructor(name) {
		this.name = name;
	}
	speak() {
		console.log('speak');
	}
	static speak() {
		console.log('static speak');
	}
}
class Programmer {
	constructor(name) {
		super(name);
	}
	static speak() {
		super.speak();
		console.log('Programmer static speak');
	}
}
Programmer.speak();
  1. 注意事项
    使用 super 的时候,必须显式指定是作为函数还是作为对象使用,否则会报错
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值