ES6 Class
ES6引入了Class(类)作为对象的模板,通过class关键字,可以定义类
ES6的class可以基本看作只是一个语法糖,它的绝大部分功能,ES5都可以做到
ES6的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
1 2 3 4 5
| class Person { constructor () {} run () {} }
|
TS Class
定义类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| interface DomCls { createElement(el:string):HTMLElement setText(el:HTMLElement,text:string|null):void render(data:Vnode):HTMLElement }
interface Vnode { tag:string text?:string children?:Vnode[] }
interface VueCls { options:Options init(): void }
interface Options { el: string|HTMLElement }
class Dom implements DomCls { createElement(el:string) { return document.createElement(el) } setText(el:HTMLElement,text:string|null) { el.textContent=text } render(data:Vnode) { let root = this.createElement(data.tag) if(data.children&&Array.isArray(data.children)) { data.children.forEach(item=> { let child = this.render(item) root.appendChild(child) }) } else { this.setText(root,data.text) } return root } }
class Vue extends Dom implements VueCls { options: Options = {el:"#app"}
constructor (options?: Options) { super() options? this.options=options: null this.init() }
init(): void { let data:Vnode = { tag:"div", children:[ { tag:"section", text:"子节点1" }, { tag:"p", 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" })
|
修饰符
readonly
表示只读,只能应用在索引签名或属性上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Vue extends Dom implements VueCls { readonly options: Options = {el:"#app"}
constructor (options?: Options) { super() options? this.options=options: null this.init() }
init(): void { } }
const v = new Vue({ el:"#app" })
|
private
表示私有,只能在这个类的内部使用,外部甚至子类都不能调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| class Dom { private createElement(el:string) { return document.createElement(el) } private setText(el:HTMLElement,text:string|null) { el.textContent=text } private render(data:Vnode) { let root = this.createElement(data.tag) if(data.children&&Array.isArray(data.children)) { data.children.forEach(item=> { let child = this.render(item) root.appendChild(child) }) } else { this.setText(root,data.text) } return root } }
class Vue extends Dom implements VueCls { options: Options = {el:"#app"}
constructor (options?: Options) { super() options? this.options=options: null this.init() }
init(): void { let data:Vnode = { }
let app = typeof(this.options.el) === "string" ? document.querySelector(this.options.el) : this.options.el app.appendChild(this.render(data)) } }
const dom = new Dom()
dom.createElement("#yajue")
|
protect
表示受保护,可以在这个类以及子类的内部使用,外部不能调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| class Dom { protected createElement(el:string) { return document.createElement(el) } protected setText(el:HTMLElement,text:string|null) { el.textContent=text } protected render(data:Vnode) { let root = this.createElement(data.tag) if(data.children&&Array.isArray(data.children)) { data.children.forEach(item=> { let child = this.render(item) root.appendChild(child) }) } else { this.setText(root,data.text) } return root } }
class Vue extends Dom implements VueCls { options: Options = {el:"#app"}
constructor (options?: Options) { super() options? this.options=options: null this.init() }
init(): void { let data:Vnode = { }
let app = typeof(this.options.el) === "string" ? document.querySelector(this.options.el) : this.options.el app.appendChild(this.render(data)) } }
const dom = new Dom()
dom.createElement("#yajue")
const v = new Vue({ el:"#app" })
v.createElement("#yajue")
|
public
表示公用,任何地方都可以调用
所有的属性和方法,如果不加修饰符,都默认为public
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| class Dom { createElement(el:string) { return document.createElement(el) } public setText(el:HTMLElement,text:string|null) { el.textContent=text } render(data:Vnode) { let root = this.createElement(data.tag) if(data.children&&Array.isArray(data.children)) { data.children.forEach(item=> { let child = this.render(item) root.appendChild(child) }) } else { this.setText(root,data.text) } return root } }
class Vue extends Dom implements VueCls { options: Options = {el:"#app"}
constructor (options?: Options) { super() options? this.options=options: null this.init() }
init(): void { let data:Vnode = { }
let app = typeof(this.options.el) === "string" ? document.querySelector(this.options.el) : this.options.el app.appendChild(this.render(data)) } }
const dom = new Dom()
dom.createElement("#yajue")
const v = new Vue({ el:"#app" })
v.setText("#yajue", "114514")
|
super
在子类中,super就代表父类,所以super()代表父类的构造函数(将this指向改为了子类),super.xxx可以取到父类的属性或方法
静态属性/方法
例如Promise.all
,静态方法直接通过类名调用
静态方法中只能调用静态属性和方法,普通方法只能调用普通属性和方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| class Vue extends Dom implements VueCls { options: Options = {el:"#app"} static a = "12321"
constructor (options?: Options) { super() options? this.options=options: null this.init() }
init(): void { let data:Vnode = { }
let app = typeof(this.options.el) === "string" ? document.querySelector(this.options.el) : this.options.el app.appendChild(this.render(data)) }
static version():string {
console.log(this.a) console.log(this.abc()) return "v 1.1.4" } static abc():string { return "???" } }
console.log(Vue.a) console.log(Vue.version())
const v = new Vue({ el:"#app" })
v.a v.version()
|
get和set
读取或设置属性时会触发get或set函数,格式为get/set [属性]() {}
可以用get和set函数做属性的拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Ref { private _value:any
constructor (value:any) { this._value = value }
get value() { console.log("我被读取了") return this._value }
set value(newVal:any) { console.log("我被修改了") this._value = newVal } }
const r = new Ref(5) console.log(r.value) r.value = 6
|
抽象类
通过abstract修饰符定义的类就是抽象类,又称基类;抽象类中通过abstract修饰符定义的方法就是抽象方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| abstract class Vue { name:string constructor(name?:string) { this.name = name }
getName():string { return this.name }
abstract init(name: string):void }
class React extends Vue {
constructor() { super("yjsp") }
init(omg:string) { console.log(omg) }
setName(name:string) { this.name = name } }
const react = new React() react.init("omg") console.log(react.getName()) react.setName("yajue") console.log(react.getName())
|