浅谈 ES6 中的 Class
2020-12-18 本文已影响0人
前端好有趣
class以及super方法
-
super关键字单独出现在子类的构造函数中,作用是通过调用父类的构造函数来为子类添加属性和赋值
class Father{ constructor(x, y){ this.x = x; this.y = y; this.name = 'Father' } sayName(){ console.log(this.name) } } class Child extends Father{ constructor(x, y){ super(x, y); this.name = 'Child'; } sayPosition(){ console.log(`x:${this.x},y:${this.y}`); } } var demo = new Child(5,10); demo; // Child { x: 5, y: 10, name: 'Child' } 子类Child通过super得到了Father的x和y属性 demo.sayPosition(); // x:5,y:10 ,sayPosition方法里面的this指向实例demo对象
-
父类和子类之间方法和属性的相互访问
- 父类静态方法访问父类静态方法用
this.staticfunctionMethod
来获取 - 父类非静态方法访问父类静态方法用
this.constructor.staticfunctionMethod
来获取 - 父类非静态方法访问父类非静态方法用
this.functionMethod
来获取 - 子类静态方法访问父类静态方法用
super.staticfunctionMethod
来获取 - 子类非静态方法访问父类静态方法用
super.constructor.staticfunctionMethod
来获取 - 子类非静态方法访问父类非静态方法用
super.functionMethod
来获取 - 子类访问父类属性需要使用
super.constructor.Property
class Father{ constructor(x, y){ this.x = x; this.y = y; this.name = 'Father' } sayName(){ console.log(this.name) } static ping(){ return 'ping'; } static bing(){ // 静态方法中直接使用 this.staticMethod 来访问父类的静态方法 console.log(`bing,${this.ping()}`); } unStatic(){ // 非静态方法中使用 this.constructor.staticMethod 来访问静态方法 console.log(this.constructor.ping()); } } Father.bing(); // bing,ping new Father().unStatic();// ping class Child extends Father{ constructor(x, y){ super(x, y); this.name = 'Child'; } test(){ // 子类不能直接访问父类属性,子类访问父类属性需要使用 `super.constructor.Property console.log(super.name,super.constructor.name); } sayName(){ // 在子类的非静态方法中访问父类静态方法用super.constructor.staticfunctionMethod console.log(super.constructor.ping()); // 在子类的非静态方法中访问父类非静态方法用super.functionMethod super.sayName(); } static bing(){ // 在子类的静态方法中访问父类静态方法用super.staticfunctionMethod console.log(`bing,${super.ping()}`); } } new Child().test(); // undefined,"Father" new Child().sayName(); // ping, Child Child.bing(); // bing,ping
- 父类静态方法访问父类静态方法用
-
this
和super
的区别-
this
关键词指向的是函数所在的当前对象 -
super
指向的是当前对象的原型对象---------------原型对象是指Father
的prototype
或者 new Child 的__proto__
//super.name指向的是原型对象person 中的name,但是绑定的this还是当前的man对象 const person = { age:'20多了', name(){ return this.age; } } const man = { age:'18岁了', sayName(){ return super.name(); } } Object.setPrototypeOf( man, person ); let n = man.sayName(); console.log( n ) // 18岁了 // Object.getPrototypeOf(this)指向的是name所在的person对象,绑定的name函数中的this也是person const person = { age:'20多了', name(){ return this.age; } } const man = { age:'18岁了', sayName(){ // 这里的this是指的man这个对象{age: 18岁了,sayName:f()} // Object.getPrototypeOf(this)指的是man这个对象的__proto__(person---{age: 20多了,name:f()}) return Object.getPrototypeOf(this).name(); // 这个返回的是 18岁了,用call改变了函数name的执行范围为man对象{age: 18岁了,sayName:f()} return Object.getPrototypeOf(this).name.call(this) } } // 把man的__proto__指向person---{age: 20多了,name:f()},用于改变man的原型指向 Object.setPrototypeOf( man, person ); let n = man.sayName(); console.log( n ) // 20多了
-
-
super
在静态方法之中指向父类,在普通方法之中指向父类的原型对象(非静态方法才会在原型对象上)class Parent { // 在Parent.ccc()调用,调用Parent.bbb()报错 warning: Parent.bbb is not a function static ccc(msg) { console.log('static', msg); } // bbb()在Parent的实例上才会有 bbb(msg) { console.log('non-static-instance', msg); } } class Child extends Parent { // aaa()在Child的实例上才会有 aaa(msg) { super.bbb(msg); } // 在Child.AAA()调用,调用Child.aaa()报错 warning: Child.aaa is not a function static AAA(msg) { super.ccc(msg); } } Child.AAA(1); // static 1 Child.aaa(1); // warning: Child.aaa is not a function var child = new Child(); child.aaa(2); // non-static-instance 2 console.log(111,Child.prototype) // aaa: ƒ aaa(msg) console.log(222,child.__proto__) // aaa: ƒ aaa(msg) console.log(333,Parent.prototype) // bbb: ƒ bbb(msg)