原型链图:
-
实例就是对象,实例的__protpo__指向的是原型对象。
-
实例的构造函数的prototype也是指向的原型对象。
-
原型对象的construor指向的是构造函数。
代码:
class One {
constructor() {
this.nameOne = 'One';
}
validateOne() {
console.log('one');
}
}
class Two extends One {
constructor() {
super();
this.nameTwo = 'Two';
}
validateTwo() {
console.log('two');
}
}
class Three extends Two {
constructor() {
super();
this.nameThree = 'three';
}
validateThree() {
console.log('three');
}
}
function getAllProperties(obj) {
function getProperty(new_obj) {
if (new_obj.__proto__ === null) {
// 说明该对象已经是最顶层的对象
return [];
}
const properties = Object.getOwnPropertyNames(new_obj);
return [...properties, ...getProperty(new_obj.__proto__)]; // 关键点
}
return getProperty(obj);
}
const three = new Three();
const data1 = getAllProperties(three); // 实例对象
const data2 = getAllProperties(Three.prototype); // 原型对象
// const data1 = Array.from(new Set(getAllProperties(three)));
// const data2 = Array.from(new Set(getAllProperties(Three.prototype)));
console.log(data1,data2);
控制台截图:
注意事项:
-
extends关键字继承父类的属性和方法。
-
ES6中类的定义能很有效地分割原型对象和实例对象。这是因为类块中定义的方法都会被当作原型对象上的方法,而类中用this关键字声明的属性又都属于不同的实例对象。
-
使用extends继承父类后,子类可以通过super关键字来访问父类的构造函数和静态方法。当子类没有显式定义自己的构造函数时,会默认继承父类的构造函数;若显式定义了构造函数,则必须引用super()或返回一个对象。
-
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。