99< body >
1010< script >
1111// class是对象模板,本质是function语法糖
12- // 类定义
12+ /**
13+ * 【 类声明 】
14+ * 注意:
15+ * 1. 类定义不会提升
16+ * 2. 不可重复声明
17+ */
1318// 匿名类
1419let 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