Ecmascript 6 是否可以撤消Object.assign?

Ecmascript 6 是否可以撤消Object.assign?,ecmascript-6,Ecmascript 6,我想使用对象。指定临时使用新方法“升级”对象,然后在使用完这些方法后删除它们。举例说明: 假设我们有一个mixin,它允许我们计算数组的平均值: var ArrayUtilMixin = { avg() { let sum = this.reduce( (prev, v) => {return prev + v}, 0); return sum / this.length; } }; 我们的客户机代码如下所示: let myArr = [0,3,2,4,88];

我想使用
对象。指定
临时使用新方法“升级”对象,然后在使用完这些方法后删除它们。举例说明:

假设我们有一个mixin,它允许我们计算数组的平均值:

var ArrayUtilMixin = {
  avg() {
    let sum = this.reduce( (prev, v) => {return prev + v}, 0);
    return sum / this.length;
  }
};
我们的客户机代码如下所示:

let myArr = [0,3,2,4,88];
// now I am in a context where I want to average this array, 
// so I dynamically add the ability with Object.assign
Object.assign(myArr, ArrayUtilMixin);
let avg = myArr.avg();
// do some stuff here with the average
// now we're done, we want declutter the myArr object
// and remove the no longer needed avg() method

Object.unassign(myArr, ArrayUtilMixin);  // <-- CAN WE DO THIS SOMEHOW?
让myArr=[0,3,2,4,88];
//现在我要对这个数组求平均值,
//因此,我使用Object.assign动态添加了该功能
赋值(myArr,ArrayUtilMixin);
设avg=myArr.avg();
//在这里用平均值做一些事情
//现在我们完成了,我们要分离myArr对象
//并删除不再需要的avg()方法
Object.unassign(myArr,ArrayUtilMixin);//
有没有办法做到这一点

有一些,但我认为没有一个能完全做到你想做的:

  • 使用
    对象。分配
    ,然后
    删除
    新属性

    Object.unassign = function(o, mixin) {
        for (var p in mixin)
            delete o[p]; // deletes own properties only, so don't fear
        return o;
    }
    
    当然,当您覆盖了自己的方法/属性时,这就不起作用了

  • 更改要扩展的对象的原型链

    function extend(o, mixin) {
        var m = Object.assign({}, mixin);
        Object.setPrototypeOf(m, Object.getPrototypeOf(o));
        Object.setPrototypeOf(o, m);
        return o;
    }
    function unextend(o) {
        Object.setPrototypeOf(o, Object.getPrototypeOf(Object.getPrototypeOf(o)));
        return o;
    }
    

    这种方法的优点是,自己的属性保持自己的属性,因此对象上的指定将照常工作。有一些语言支持这种模式(并将其与多重继承相结合),但我不确定它是否真的有效。当然,在JavaScript中修改原型链是一个非常糟糕的主意

  • 为原型链添加前缀

    function extended(o, mixin) {
        return Object.assign(Object.create(o), mixin);
    }
    
    这将使用从实际对象继承的mixin方法创建一个新对象。只需扔掉临时的,然后再次使用旧的(我想这不完全是您心目中的使用模式?)-您可以通过将旧的存储在属性中并使用
    unexpend()
    函数“展开”来隐藏这一事实

    当然,这种简单而高效的模式的缺点是对临时对象的赋值不起作用。它们将创建新的、自己的属性,而不是修改实际对象,并且一旦您“取消维护”,它们将被丢弃。这对于您的
    avg
    方法来说并不重要,甚至可以用于某些混音,但您可能不希望这样

如果不是,我是否使用了错误的语言功能

这很可能是因为它没有语言特性


对于这种情况,最常见的建议是构造一个包装器对象(例如围绕DOM对象),它充当用户和实际对象之间的代理。包装器的API与包装对象的API完全不同;这不是一个简单的“扩展”。

您可以简单地迭代
ArrayUtilMixin
的属性,然后从
myArr
中删除它们。仅当分配
ArrayUtilMixin
不会覆盖
myArr
的任何属性时,该方法才有效。另一个有趣的方法是将
ArrayUtilMixin
插入
myArr
的原型链。当然,在JavaScript中修改原型链是一个非常糟糕的主意——为什么这样不好?特别是在你给出的例子中?谢谢。@Jonah:请看“有些语言支持这种模式(并将其与多重继承相结合)”——这些模式的最佳示例是什么?@Jonah:是的,我认为Self或NewtonScript也是如此。