Skip to content

Commit 113ba99

Browse files
es6
1 parent 81238a7 commit 113ba99

File tree

1 file changed

+259
-2
lines changed

1 file changed

+259
-2
lines changed

02-ES新特性/ES6/12-ES6-Class类.html

Lines changed: 259 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,276 @@
99
<body>
1010
<script>
1111
// class是对象模板,本质是function语法糖
12-
// 类定义
12+
/**
13+
* 【 类声明 】
14+
* 注意:
15+
* 1. 类定义不会提升
16+
* 2. 不可重复声明
17+
*/
1318
// 匿名类
1419
let Example1 = class {
1520
constructor(a) {
1621
this.a = a;
1722
}
1823
}
1924
// 命名类
20-
let Example2 = class Example {
25+
class Example2 {
2126
constructor(a) {
2227
this.a = a;
2328
}
2429
}
30+
31+
/**
32+
* 【 类的主体 】
33+
*/
34+
// 【 属性 】
35+
// - prototype 虽可以直接在类中定义方法,但方法本质上还是定义在prototype上的
36+
class Example3 {
37+
func1 () { return 'ret-func1' }
38+
}
39+
Object.assign(Example3.prototype, {
40+
// 添加方法
41+
func2: function () { return 'ret-func2' }
42+
})
43+
var exam3 = new Example3('csxiaoyao');
44+
console.log(exam3.func1(), exam3.func2()) // ret-func1 ret-func2
45+
46+
// - name 属性
47+
let Example4 = class Example4 {}
48+
console.log(Example4.name); // Example4 返回class后的类名(存在时)
49+
50+
// - 公共属性
51+
class Example5{}
52+
Example5.prototype.a = 1;
53+
console.log((new Example5()).a) // 1
54+
55+
class Example6 {
56+
a = 1; // 实例属性,定义在实例对象( this )上的属性
57+
constructor () {
58+
console.log(this.a);
59+
}
60+
}
61+
new Example6() // 1
62+
63+
// - 静态属性
64+
class Example7 {
65+
static a = 1;
66+
}
67+
Example7.b = 2;
68+
console.log(Example7.a, Example7.b) // 1 2
69+
70+
// 【 方法 】
71+
// - constructor 方法返回对象 (类的默认方法,实例化对象时被调用)
72+
class Example8 {
73+
constructor(){
74+
console.log('constructor');
75+
// 默认返回实例对象 this
76+
}
77+
}
78+
console.log(new Example8() instanceof Example8); // true
79+
// - 原型方法
80+
class Example9 {
81+
sum(a, b) {
82+
return a+b;
83+
}
84+
}
85+
let exam9 = new Example9();
86+
console.log(exam9.sum(1, 2)); // 3
87+
// - 实例方法
88+
class Example10 {
89+
constructor() {
90+
this.sum = (a, b) => {
91+
return a+b;
92+
}
93+
}
94+
}
95+
let exam10 = new Example10();
96+
console.log(exam10.sum(1, 2)); // 3
97+
// - 静态方法
98+
class Example11{
99+
static sum (a, b) {
100+
return a+b;
101+
}
102+
}
103+
console.log(Example11.sum(1, 2)); // 3
104+
105+
/**
106+
* 【 实例化 】
107+
*/
108+
// 共享原型对象
109+
class Example12 {
110+
constructor(a, b) {
111+
this.a = a;
112+
this.b = b;
113+
}
114+
sum () {
115+
return this.a + this.b;
116+
}
117+
}
118+
let exam12_1 = new Example12(2, 1), exam12_2 = new Example12(3, 1);
119+
exam12_1.__proto__.sub = function() {
120+
return this.a - this.b;
121+
}
122+
console.log(exam12_1.sub(), exam12_2.sub()); // 1 2 共享方法sub
123+
124+
/**
125+
* 【 decorator 】
126+
* decorator是在代码编译时修改类的行为的函数
127+
*/
128+
// 【 类修饰 】
129+
// 一个参数 target,指向类本身
130+
/*
131+
function testable(target) {
132+
target.isTestable = true;
133+
}
134+
@testable
135+
class Example13 {}
136+
Example13.isTestable; // true 添加静态属性,若要添加实例属性,在类的 prototype 上操作即可
137+
*/
138+
// 多个参数——嵌套实现
139+
/*
140+
function testable(isTestable) {
141+
return function(target) {
142+
target.isTestable=isTestable;
143+
}
144+
}
145+
@testable(true)
146+
class Example14 {}
147+
Example14.isTestable; // true
148+
*/
149+
// 【 方法修饰 】
150+
// 3个参数:target(类的原型对象)、name(修饰的属性名)、descriptor(该属性的描述对象)
151+
/*
152+
class Example15 {
153+
@writable
154+
sum(a, b) {
155+
return a + b;
156+
}
157+
}
158+
function writable(target, name, descriptor) {
159+
descriptor.writable = false;
160+
return descriptor; // 必须返回
161+
}
162+
*/
163+
// 修饰器执行顺序:由外向内进入,由内向外执行
164+
/*
165+
class Example16 {
166+
@logMethod(1)
167+
@logMethod(2)
168+
sum(a, b){
169+
return a + b;
170+
}
171+
}
172+
function logMethod(id) {
173+
console.log('evaluated logMethod '+id);
174+
return (target, name, desctiptor) => console.log('excuted logMethod '+id);
175+
}
176+
// evaluated logMethod 1
177+
// evaluated logMethod 2
178+
// excuted logMethod 2
179+
// excuted logMethod 1
180+
*/
181+
182+
/**
183+
* 【 封装与继承 】
184+
* getter / setter
185+
*/
186+
class Example16{
187+
constructor(a, b) {
188+
this.a = a;
189+
this.b = b;
190+
}
191+
// getter 不可单独出现
192+
get a(){
193+
console.log('getter');
194+
// return this.a;
195+
return this._a;
196+
}
197+
set a(a){
198+
console.log('setter');
199+
// this.a = a; // 自身递归调用,不断输出 setter ,最终导致 RangeError
200+
this._a = a;
201+
}
202+
}
203+
let exam16 = new Example16(1,2); // 只输出 setter , 不会调用 getter 方法
204+
console.log(exam16.a, exam16._a); // 1 1
205+
// getter 与 setter 必须同时同级出现
206+
class Father1 {
207+
constructor(){}
208+
get a() {
209+
return this._a;
210+
}
211+
}
212+
class Child1 extends Father1 {
213+
constructor(){
214+
super();
215+
}
216+
set a(a) {
217+
this._a = a;
218+
}
219+
}
220+
let exam17 = new Child1();
221+
exam17.a = 2;
222+
console.log(exam17.a); // undefined
223+
224+
/**
225+
* 【 extends & super 】
226+
* extends 继承,子类 constructor 方法中必须有 super ,且必须出现在 this 之前
227+
*/
228+
class Father2 {
229+
constructor() {}
230+
}
231+
// error1 [有constructor必须有super] Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
232+
/* class Child2 extends Father2 { constructor() {} } */
233+
// error2 [super必须在this前] Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
234+
/*
235+
class Child2 extends Father2 {
236+
constructor(a) {
237+
this.a = a;
238+
super();
239+
}
240+
}
241+
*/
242+
class Child2 extends Father2 {} // ok
243+
class Child3 extends Father2 { // ok
244+
constructor(a) {
245+
super(a)
246+
this.a = a
247+
}
248+
}
249+
let exam18 = new Child2();
250+
let exam19 = new Child3(1);
251+
console.log(exam19.a) // 1
252+
253+
// super调用父类方法,在普通方法中指向父类的原型对象,在静态方法中指向父类
254+
class Father3 {
255+
test(){
256+
return 0;
257+
}
258+
static test1(){
259+
return 1;
260+
}
261+
}
262+
class Child4 extends Father3 {
263+
constructor(){
264+
super();
265+
// 调用父类普通方法
266+
console.log(super.test()); // 0
267+
}
268+
static test2(){
269+
// 调用父类静态方法
270+
return super.test1() + 2;
271+
}
272+
}
273+
console.log(Child4.test2()); // 3
274+
275+
// 注意要点: 不可直接继承常规对象
276+
var Father4 = {}
277+
// class Child5 extends Father4 {} // error
278+
// 解决方案
279+
class Child5{}
280+
Object.setPrototypeOf(Child5.prototype, Father4);
281+
25282
</script>
26283
</body>
27284
</html>

0 commit comments

Comments
 (0)