Class继承相关笔记

89 阅读3分钟

1. 静态属性   静态方法    私有属性   私有方法

class Person {    
   #wife = '李小慧'      //声明私有属性(只能在类的内部使用)     
  _person = '张小黑'    //声明实例属性(不用写到constructor构造函数中)     
  static happy() {     //声明静态方法,只能是通过类进行访问         
    console.log('哈哈哈')     
  }     
  hi(zhaohu) {          //声明实例方法         
    hello.call(this, zhaohu)   //实现私有方法的一种实现     
  } 
}    
const heihei = new Person();    //创建实例    
heihei.hi('cao')                //在这个过程中,访问了类的私有方法    
Person.hello = 'HELLO'          //声明静态属性    
Person.happy()                  //访问class类的静态方法         
function hello(zhaohu) {       //定义在类外的“静态方法”        
   console.log(this._person + zhaohu)    
}

2. 静态块

3. new target 

     如果并不是通过new 或者Reflct.constructor创建的实例,在类的内部new.target会返回undefined,否则就返回当前类。子类继承的话,会返回子类的Class

4. 继承

1. 在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前子类实例

2. 在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例

5. 关于继承的__proto__和prototype

在说es6的继承之前,有一个知识点要先明白:

    _  __proto__这个属性串起了原型链,而这个原型链说的简单点就是找一个对象的某个属性(自己身上找不到,就顺着原型链一级一级的网上找)。所以并不是说__proto__一定要指向到某个构造函数的原型对象(obj.prototype),而是可以执行到任何的对象上,从而实现属性上的继承_

现在来梳理es6类的__proto__和prototype(代码就直接从阮一峰老师的es6入门一文上抓了)

class A {
}

class B extends A {
}

这里的exteds的内部实现,可以理解为以下两个操作
// 1. B 的实例继承 A 的实例
Object.setPrototypeOf(B.prototype, A.prototype);
// 2. B 继承 A 的静态属性
Object.setPrototypeOf(B, A);

// 而setPrototypeOf的内保部实现是
Object.setPrototypeOf = function (obj, proto) {
   obj.__proto__ = proto;  return obj;
}

由上代码得出

class A {
}

class B extends A {
}
就等同于
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true

阮一峰老师做了注解说、

这两条继承链,可以这样理解:作为一个对象,子类(B)的原型(__proto__属性)是父类(A);作为一个构造函数,子类(B)的原型对象(prototype属性)是父类的原型对象(prototype属性)的实例。

在此基础上再加一些自己的大白话理解 :

一个class类,他有两种属性,一个是静态属性(类名.静态属性-->A.prpo1这样的方式进行访问),第二就是实例属性(A.prototype.prop2这样的形式进行访问)

所以,才会有了上面两个用__proto__改变原型链的指向,就是为了将A上的所有属性全都继承给B

这样就能得出下面的子类实例的__proto__与父类实例的__proto__二者的关系了

var p1 = new A();
var p2 = new B();

p2.__proto__.__proto__ === p1.__proto__ // true

p2.__proto__=B.prototype

由于继承的特性

B.prototype.__proto__=A.prototype

A.prototype=p1.__proto__

所以 p2.__proto__.__proto__ === p1.__proto__

因此,通过子类实例的__proto__.__proto__(p2.__proto__.__proto__)属性,可以修改父类实例的行为。

_es6.ruanyifeng.com/#docs/class…
_