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__)属性,可以修改父类实例的行为。