我尝试通过spread operator 语法在getter中创建混合到JS对象中,但是它似乎总是返回<body>
<div id="wrapperA"></div>
<div id="wrapperB"></div>
</body>
<script src='./test.js'></script>
。
HTML:
"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);
JS:
{wrappername: "wrapperA", wrapper: null}
{wrappername: "wrapperB", wrapper: null}
控制台输出:
...
This链接到一个应该起作用的扩展函数,从我可以告诉上面的代码创建了一个无意的闭包。但是,与/product/payment/checkTransaction
语法相比,它读取的效果非常差。有人知道如何让代码与后一种解决方案一起使用吗? ES开发人员是否了解此问题并将在ES7中修复?
答案 0 :(得分:5)
这不是错误。解释扩展语法时,将评估mixin
的属性值,即wrapper
getter在this
设置为mixin
的情况下调用。请注意,this
不正在构建的新对象,而...
has precedence超过了逗号排序。因此,在执行...
时,最终对象不在视图中。其次,复制的属性不再是getter,而是具有原子值(不是函数)的普通属性。
使用Object.assign
时执行的几乎相同的过程可以更好地理解行为:
Object.assign({
wrappername: 'wrapperA'
}, mixin);
如果您希望使用新对象wrapper
调用this
getter,请执行以下操作:
"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这样的库,这使得这很容易。
在mixin实现on StackOverflow上有几个Q&amp; A。以下是源自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>
虽然这有效地提供了多重继承,但是从表达式派生的类的层次结构实际上并不是高效代码的成分。
另一种方法是放弃mixins的想法而改为使用装饰器:
"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>
这导致了一个扁平结构(没有原型链),其中扩展发生在目标对象本身。