class Parent {
constructor(firstName, name, age) {
this.Pname = name;
this.Page = age;
this.firstName = firstName;
this.dying = function() {
console.log("parent is dying");
return "parent is dying"
};
}
static psleeping() {
console.log("sleeping");
}
Pmoving() {
console.log("parent is moving");
}
}
class Child extends Parent {
constructor(Cname, firstName) {
super(firstName);
this.Cname = Cname;
this.dying = function() {
console.log("child is dying");
return "child is dying"
};
}
static Csleep() {
console.log("child is sleeping");
}
leaving() {
console.log("child is leaving");
}
}
Child.prototype.hi = function() {
console.log("hi");
};
const child = new Child("childTom", "first");
console.log(child);
console.log(child.dying());
console.log(child.firstName);
const o = Object.getPrototypeOf(child);
console.log(o);
const o2 = Object.getOwnPropertyNames(o);
console.log(o2);
for (let each in o) {
console.log(each);
}
for (let each in child) {
console.log(each);
if(child.hasOwnProperty(each)){
console.log(child[each])
}
console.log(child[each]);
}
console.log(Object.keys(child));
// console.log(Object.keys(a));
console.log(Object.values(child));
console.log(child.hasOwnProperty("Csleep"));
console.log(Object.getOwnPropertyNames(child));
console.log(child.Pmoving);
[(image.png-b2075e-1557370414021-0)]
image.png
对于结果的一些解释
- 对于所有在constructor里面声明的变量方法,都会被实列得到,不管这个属性是在父类还是子类中.这种算实列化属性,不算在继承里面,如果子类属性和父类属性冲突了,会以子类属性为主.
- 因为class里面定义在constructor外面的的非静态方法都是在原型对象上,并且是不可枚举的.
所以for....in虽然本身能遍历到一个对象的原型上,但是class的方法是不可枚举的,所以是遍历不到的class里面的方法的.
Object.keys和Object.values, hasOwnProperty都是不遍历原型链的,但是hasOwnProperty可以遍历到不可枚举的属性(严格来讲,这不算遍历,这只是判断对象是否有这个属性).Object.keys和for...in虽然看起来结果一样(这里不考虑在Child.prototype.添加属性这种情况),但是性质不一样.
Object.keys是因为不遍历原型链而获取不到class的方法.
for....in是因为遍历原型链但是方法不可枚举从而导致获取不到class的方法.
- Object.getPrototypeOf是获取这个对象的原型对象.
Object.getOwnPropertyNames()是获取对象的所有属性(包括不可枚举的属性)
两者结合就能获取到class的方法了(constructor这个也被获取到了)
const o = Object.getPrototypeOf(child);
const o2 = Object.getOwnPropertyNames(o);
网友评论