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

时间:2016-05-13 21:23:58

标签: javascript prototype mixins

我试图遵循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 +")");

我想让剑客mixin调整玩家的基础健康状况。我尝试使用'this',但它没有帮助。我开始认为我接近这完全错了。我到底错在了什么?

2 个答案:

答案 0 :(得分:1)

问题在于您使用this的方式。当您定义对象时,this仍然引用周围的范围,而不是您定义的新对象:

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);

答案 1 :(得分:1)

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);