如何使用 Object.assign() 从其他对象引用基础对象属性

How to reference base object properties from other objects using Object.assign()

我正在尝试遵循 Kyle Simpson 关于仅使用对象而非函数的实际原型继承的想法。我想看看我是否可以使用 Object.create 和 Object.assign 将 mixins 添加到对象中,这完全有效。然后我尝试更进一步,将 mixin 中的一些属性值基于基础对象中 属性 的值。对于我尝试使用的值,我总是得到 NaN。这是代码:

function generatorFactory() {
    var basePlayer = {
        x: 0,
        y: 0,
        baseHealth: 50
    };

    var generatePlayer = function() {
        return basePlayer;
    };
    return generatePlayer;
}

var playerGenerator = generatorFactory();
var basicPlayerObject = playerGenerator();

var heavyArmor = {
    defense: 15,
    attack: 9
};

var lightArmor = {
    defense: 7
};

var swordsman = {
    health: this.baseHealth + 10
};

var knifeFighter = {
    health: this.baseHealth - 10
};

var sigurd = Object.assign(Object.create(basicPlayerObject), heavyArmor, swordsman);

console.log(sigurd.health);
console.log(sigurd.defense);
console.log(sigurd.attack);
console.log("Player coordinates: (" + sigurd.x + ", " + sigurd.y +")");

我想让剑士混合调整玩家的基础生命值。我尝试使用 'this',但没有帮助。我开始认为我正在接近这个完全错误的。我到底做错了什么?

问题在于您使用 this 的方式。当你定义一个对象时,this 仍然指的是 surrounding 作用域,而不是你定义的新对象:

var self = this;
var swordsman = {
    checkThis: self === this // true
};

完成您想要做的事情的一种方法是将这些对象更改为函数。

function initSwordsman(obj) {
    obj.health = obj.baseHealth + 10;
}
var sigurd = Object.assign(Object.create(basicPlayerObject), heavyArmor);
initSwordsman(sigurd);

this in your object literals 不是您所期望的。如果您希望它动态引用访问 属性 的对象,则需要使用 getter:

var swordsman = {
    health: {
        get() { return this.baseHealth + 10; },
        enumerable: true,
        configurable: true
    }
};

var knifeFighter = {
    health: {
        get() { this.baseHealth - 10 },
        enumerable: true,
        configurable: true
    }
};

并且您需要将那些 属性 描述符传递给 Object.create 而不是 Object.assign:

var sigurd = Object.assign(Object.create(basicPlayerObject, swordsman), heavyArmor);