ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用ES6的"类"改写,就是下面这样。
//定义类
class Person {
constructor () {
}
run () {
}
}
在ts中如何定义class类
在TypeScript是不允许直接在constructor 定义变量的 需要在constructor上面先声明
你如果了定义了变量不用 也会报错 通常是给个默认值 或者 进行赋值
class Person {
name: string;
age: number;
sex:number = 0 //默认值
constructor(name: string, age: number) {
this.name = name
this.age = age
}
run() {
}
}
类的修饰符 public private protected
总共有三个 public private protected
使用public 修饰符 可以让你定义的变量 内部访问 也可以外部访问 如果不写默认就是public
使用 private 修饰符 代表定义的变量私有的只能在内部访问 不能在外部访问
class Person {
public name: string;
private age: number;
protected sex: number = 0; //默认值
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
run() {}
}
const peo = new Person('xx',23)
console.log(peo.name)
使用 protected 修饰符 代表定义的变量私有的只能在内部和继承的子类中访问 不能在外部访问
class Person {
public name:string
private age:number
protected some:any
constructor (name:string,ages:number,some:any) {
this.name = name
this.age = ages
this.some = some
}
run () {
}
}
class Man extends Person{
constructor () {
super("张三",18,1)
console.log(this.some)
}
create () {
console.log(this.some)
}
}
let xiaoman = new Person('小满',18,1)
let man = new Man()
man.some //报错
static 静态属性 和 静态方法
我们用static 定义的属性 不可以通过this 去访问 只能通过类名去调用
static 静态函数 同样也是不能通过this 去调用 也是通过类名去调用
需注意: 如果两个函数都是static 静态的是可以通过this互相调用
javascript
class Person {
static xxx: string = "66";
private age: number;
constructor(ages: number) {
this.age = ages;
// this.xxx //静态属性无法用this调用
}
run() {
console.log(Person.xxx);
// this.test1 //static 静态函数 同样也是不能通过this 去调用 也是通过类名去调用
}
static test1() {
return "aaa";
}
static test2() {
console.log(Person.test1());
}
}
console.log(Person.xxx);
Person.test2();
interface 定义 类
javascript
interface PersonClass {
get(type: boolean): boolean
}
interface PersonClass2{
set():void,
asd:string
}
class A {
name: string
constructor() {
this.name = "123"
}
}
class Person extends A implements PersonClass,PersonClass2 {
asd: string
constructor() {
super()
this.asd = '123'
}
get(type:boolean) {
return type
}
set () {
}
}
抽象类
应用场景如果你写的类实例化之后毫无用处此时我可以把他定义为抽象类
或者你也可以把他作为一个基类-> 通过继承一个派生类去实现基类的一些方法
我们看例子
下面这段代码会报错抽象类无法被实例化
abstract class A {
public name:string
}
new A()
例子2
我们在A类定义了 getName 抽象方法但为实现
我们B类实现了A定义的抽象方法 如不实现就不报错 我们定义的抽象方法必须在派生类实现
// abstract定义的抽象类ref是不能实例化的
abstract class Ref {
name: string;
constructor(name?: string) {
// 实例化的时候可不传name值
this.name = name;
}
getName(): string {
return this.name;
}
abstract init(name: string): void;
}
// 派生类
class React extends Ref {
constructor() {
super();
}
init(name: string) {}
setName(name: string) {
this.name = name;
}
}
const react = new React();
react.setName("xxx");
console.log(react.getName());
虚拟dom ts版本
javascript
// implements使用
interface Options {
el: string | HTMLElement;
}
interface VueCls {
options: Options;
init: () => void;
}
interface Vnode {
tag: string; //div header
text?: string; // 123可选
children?: Vnode[];
}
// 虚拟Dom简单版
class Dom {
createEl(el: string) {
return document.createElement(el);
}
// 填充文本
setText(el: HTMLElement, text: string | null) {
el.textContent = text;
}
//
render(data: Vnode) {
let root = this.createEl(data.tag);
if (data.children && Array.isArray(data.children)) {
data.children.forEach((item) => {
let child = this.render(item); //递归 不确定children有多少层
root.appendChild(child);
});
} else {
this.setText(root, data.text);
}
return root;
}
}
// Vue extends Dom vue是子类继承了父类Dom 需super()
class Vue extends Dom implements VueCls {
options: Options;
constructor(options: Options) {
super(); //放在最上面
this.options = options;
this.init();
}
init(): void {
// 虚拟Dom 通过js渲染真实的Dom
let data: Vnode = {
tag: "div",
children: [
{
tag: "section",
text: "子节点1",
},
{
tag: "section",
text: "子节点2",
},
],
};
let app =
typeof this.options.el == "string"
? document.querySelector(this.options.el)
: this.options.el;
app.appendChild(this.render(data)); // 子类调用父类的方法
}
}
new Vue({
el: "#app",
});