Javascript:在吸气剂中混合(对象扩散) [英] Javascript: Mixing in a getter (object spread)

查看:81
本文介绍了Javascript:在吸气剂中混合(对象扩散)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试通过扩展的 operator 语法在吸气剂中创建混合到JS对象中,但是它似乎总是返回null.

I tried creating mixing in a getter into a JS object via the spread operator syntax, however it always seems to return null.

HTML:

<body>
  <div id="wrapperA"></div>
  <div id="wrapperB"></div>
</body>
<script src='./test.js'></script>

JS:

"use strict";

const mixin = {
    get wrapper() { return document.getElementById(this.wrappername); }
}

const wrapperA = {
  wrappername: 'wrapperA',
  ...mixin
}

const wrapperB = {
  wrappername: 'wrapperB',
  ...mixin
}

console.log(wrapperA);
console.log(wrapperB);

控制台输出:

{wrappername: "wrapperA", wrapper: null}
{wrappername: "wrapperB", wrapper: null}

链接到扩展应该可以正常工作的功能,从我上面的代码可以看出,这造成了意外关闭.但是,与...语法相比,它的读取效果很差.有人知道如何使代码与后一种解决方案一起使用吗? ES开发人员是否知道此问题,ES7中会解决此问题吗?

This links to an extension function that is supposed to work, and from what I can tell the code above created an unintentional closure. However, it reads quite poorly compared to the ... syntax. Does anybody know how to get the code to work with the latter solution? Do the ES devs know about this issue and will it be fixed in ES7?

推荐答案

这不是错误.解释了扩展语法时,将分别评估mixin的属性值,即在this设置为mixin的情况下调用wrapper getter.请注意,this不是正在构造的新对象,例如...

This is not a bug. When the spread syntax is interpreted, the property values of mixin are each evaluated, i.e. the wrapper getter is called with this set to mixin. Note that this is not the new object that is being constructed, as ... has precedence over the comma sequencing. So at the moment the ... is executed, the final object is not in view. Secondly, the copied property is no longer a getter, but a plain property with an atomic value (not a function).

使用Object.assign时执行的几乎相同的过程也许可以更好地理解其行为:

The behaviour can maybe be better understood with the almost identical process that executes when you use Object.assign:

Object.assign({
  wrappername: 'wrapperA'
}, mixin);

如果要使用新对象this调用wrapper吸气剂,请执行以下操作:

If you want the wrapper getter to be called with the new object as this, then do:

"use strict";

class Wrapper {
    constructor(wrappername) {
        this.wrappername = wrappername;
    }
    get wrapper() {
        return document.getElementById(this.wrappername); 
    }
}

const wrapperA = new Wrapper('wrapperA');
const wrapperB = new Wrapper('wrapperB');

console.log(wrapperA.wrapper);
console.log(wrapperB.wrapper);

<div id="wrapperA"></div>
<div id="wrapperB"></div>

如果您确实需要多重继承,请查看诸如 Ring.js 之类的库,这真的很容易.

If you really need multiple inheritance, then look at a library such as Ring.js, which makes this really easy.

关于mixin实现的一些问答集关于StackOverflow .这是本文:

There are several Q&A on mixin implementations on StackOverflow. Here is one of the many ideas, derived from this article:

"use strict";
function MixinNameGetter(superclass) {
    return class extends superclass {  
        get wrapper() {
            return document.getElementById(this.wrappername); 
        }
    }
}

function MixinLetterGetter(superclass) {
    return class extends superclass {  
        get letter() {
            return this.wrappername.substr(-1); 
        }
    }
}

class Wrapper {
    constructor(wrappername) {
        this.wrappername = wrappername;
    }
}

class ExtendedWrapper extends MixinNameGetter(MixinLetterGetter(Wrapper)) {
}

const wrapperA = new ExtendedWrapper('wrapperA');
const wrapperB = new ExtendedWrapper('wrapperB');

console.log(wrapperA.wrapper, wrapperA.letter);
console.log(wrapperB.wrapper, wrapperB.letter);

<div id="wrapperA"></div>
<div id="wrapperB"></div>

尽管这有效地提供了多重继承,但是从表达式派生的类的最终层次结构实际上并不是有效代码的组成部分.

Although this effectively provides multiple inheritance, the resulting hierarchy of classes derived from expressions is not really an ingredient for efficient code.

另一种方法是放弃mixins的想法,而改用装饰器:

Another approach is to abandon the idea of mixins and use decorators instead:

"use strict";
function DecoratorNameGetter(target) {
    Object.defineProperty(target, 'wrapper', {
        get: function () { 
            return document.getElementById(this.wrappername); 
        }
    });
}

function DecoratorLetterGetter(target) {
    Object.defineProperty(target, 'letter', {
        get: function () {
            return this.wrappername.substr(-1); 
        }
    });
}

class Wrapper {
    constructor(wrappername) {
        this.wrappername = wrappername;
        DecoratorNameGetter(this);
        DecoratorLetterGetter(this);
    }
}

const wrapperA = new Wrapper('wrapperA');
const wrapperB = new Wrapper('wrapperB');

console.log(wrapperA.wrapper, wrapperA.letter);
console.log(wrapperB.wrapper, wrapperB.letter);

<div id="wrapperA"></div>
<div id="wrapperB"></div>

这导致平面结构(没有原型链),其中扩展发生在目标对象本身中.

This leads to a flat structure (no prototype chain) where the extension happens in the target object itself.

这篇关于Javascript:在吸气剂中混合(对象扩散)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆