2

如果我理解正确,object.hasOwnProperty()应该在父类的继承属性上返回 false。但是,以下代码对自己的属性和继承的属性都返回 true。

我的理解/代码是不正确还是hasOwnPropery()不正确?如果是我,如何区分自己的财产和继承的财产?

编辑:我已将我的用例添加到示例代码中。

我希望孩子fromDb()只会处理自己的属性,相反,它会覆盖父级设置的属性fromDb()

class Parent {
    parentProp = '';
    fromDb(row: {}) {
        for (const key of Object.keys(row)) {
            if (this.hasOwnProperty(key)) {
                if (key === 'parentProp') {
                    // Do some required data cleansing
                    this[key] = row[key].toUpperCase()
                } else {
                    this[key] = row[key];
                }
            }
        };
        return this;
    }
}

class Child extends Parent {
    childProp = '';
    fromDb(row: {}) {
        super.fromDb(row);
        for (const key of Object.keys(row)) {
            if (this.hasOwnProperty(key)) {
                this[key] = row[key];
            }
        };
        return this;
    }
}

let row = {
    parentProp: 'parent',
    childProp: 'child',
}

let childObj = new Child().fromDb(row);
console.log(childObj);

安慰:

Child:
    childProp: "child"
    parentProp: "parent"
4

2 回答 2

5

在生成的extends代码中,属性被复制到子类中,如下所示:

function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };

这意味着您的子类 ( d) 被赋予了它自己的属性。

这实际上与使用纯 JavaScript 继承没有什么不同:

function Parent() {
    this.parentProp = `I'm defined by Parent`;
}

function Child() {
  Parent.call(this);
  this.childProp = `I'm defined by Child`;
}

let childObj = new Child();

for (const key of Object.keys(childObj)) {
    console.log(key, childObj.hasOwnProperty(key));
}

如果您就您需要实现的目标给我们一些指导,我相信我们会找到适合您的机制来克服这个障碍。

具体用例

对于您的特定用例,您可以通过调用超类的位置来设置谁“获胜”的先例。

获取输出

childProp: "child"
parentProp: "PARENT"

让父级运行“第二”,而不是“第一”:

class Child extends Parent {
    childProp = '';
    fromDb(row: {}) {
        for (const key of Object.keys(row)) {
            if (this.hasOwnProperty(key)) {
                this[key] = row[key];
            }
        };

        super.fromDb(row); // <-- last update wins
        return this;
    }
}

超级动态属性的东西

这将动态地从子项中排除父键,从父项中排除子键...添加console.log语句以查看内部...

class Parent {
    parentProp = '';
    fromDb(row: {}) {

        const ownKeys = Object.keys(new Parent());

        for (const key of Object.keys(row)) {
            if (ownKeys.indexOf(key) > -1) {
                if (key === 'parentProp') {
                    // Do some required data cleansing
                    this[key] = row[key].toUpperCase()
                } else {
                    this[key] = row[key];
                }
            }
        };
        return this;
    }
}

class Child extends Parent {
    childProp = '';
    fromDb(row: {}) {
        super.fromDb(row);

        const ownKeys = this.getKeys();

        for (const key of Object.keys(row)) {
            if (ownKeys.indexOf(key) > -1) {
                this[key] = row[key];
            }
        };
        return this;
    }

    getKeys() {
        const childKeys = Object.keys(this);
        const parentKeys = Object.keys(new Parent());

        return childKeys.filter( function( el ) {
             return parentKeys.indexOf( el ) < 0;
        });
    }
}

let row = {
    parentProp: 'parent',
    childProp: 'child',
}

let childObj = new Child().fromDb(row);
console.log(childObj);
于 2017-10-19T08:32:47.477 回答
0

类只是旧的构造函数语法的语法糖。类中定义的属性始终是编译为构造函数中设置的值的实例属性:

function Parent() {
    this.parentProp = "I'm defined by Parent";
}

该属性不是来自原型,它是this在构造函数中设置的实例属性。只有方法在原型上共享。如果您想要共享属性,则必须声明它们static;但是它们是类属性,也不在原型上。

于 2017-10-19T08:28:45.517 回答