自己的一点思考
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
</html>
<script>
class A {
// 属性
a = 'a'
sayA () {
console.log('这是A的方法');
}
}
class B extends A {
// 属性
b = 'b'
// 方法
sayB () {
console.log(
'这是B的方法'
);
}
}
class C extends B {
// 属性
c = 'c'
//方法
sayC (){
console.log('这是C的方法');
}
}
// prototype 的关系
console.log(A.prototype)
console.log(A.prototype.__proto__);
console.log(A.prototype.__proto__.__proto__);
const a = new A()
const b = new B()
const c = new C()
// 1. c 是 C 的实例化对象,那么 c 会拷贝一份 C 的属性在自己的栈储存中,方法会存储在 C 的prototype 中
// 2. 而方法会存储在构造函数 C 的 prototype 中,当 new C() 的时候会将这个对象的__proto__ 赋值为构造函数C的prototype
console.log('c',c); // c 的 值为 {a: 'a', b: 'b', c: 'c'} 也就是说它会拷贝一份 A 和 B 类里面的数据,然后再通过原型链继承方法
// 3. 而 C 的 prototype 是通过 B 类构造出来的 相当于 C.prototype = new B()
console.log('C.prototype', C.prototype);
// 4. 因为是通过 B 构造出来的, 自然有 C.prototype = new B() ,然后再添加上 C 中定义的方法
// 5. 由于 C.prototype 是 B 构造的,C.prototype 就是 B 的实例化对象。那么自然有实例化对象 C.prototype 的 __proto__ 为 B 的prototype
console.log('C.prototype.__proto__ === B.prototype', C.prototype.__proto__ === B.prototype);
// 由于 b 是 B 的实例化对象,那么 b 会拷贝一份 B 的属性,并且通过b.__proto 来继承方法
console.log('---------------');
// 一个构造函数被定义的时候就会有一个 prototype 属性,它是一个对象。是通过实例化它的父级构造函数得到的
// 如何证明呢?
// 因为它是一个实例化对象,所以在它被 实例化 的时候会 传入一个 __proto__ 对象。它的值就等于它的构造函数 prototype 属性
// 而刚好这个 构造函数的 prototype 下会有一个 constructor 属性 指向的是 这个构造函数本身
// 因此我们可以通过 实例化对象.__proto__.constructor 得知这个实例化对象是由哪个构造函数构造出来的
console.log('C.prototype instanceof B', C.prototype instanceof B)
// 因此在这里得知 C.prototype 的构造函数就是 B
console.log('C.prototype.__proto__.constructor', C.prototype.__proto__.constructor);
console.log('C.prototype', C.prototype);
</script>