gpt4 book ai didi

Javascript:混入 setter/getter (对象传播)

转载 作者:行者123 更新时间:2023-11-29 16:04:26 25 4
gpt4 key购买 nike

我尝试通过传播 operator 语法将 getter 混合到 JS 对象中,但它似乎总是返回 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}

This链接到一个应该工作的扩展函数,据我所知,上面的代码创建了一个无意的关闭。但是,与 ... 语法相比,它的可读性很差。有人知道如何让代码与后一种解决方案一起使用吗? ES 开发者知道这个问题吗?它会在 ES7 中修复吗?

最佳答案

这不是错误。当传播语法被解释时,mixin 的属性值分别被评估,即 wrapper getter 被调用,this 设置为 混入。请注意,this 不是正在构造的新对象,如 ... has precedence在逗号排序。所以在 ... 执行的那一刻,最终对象不在 View 中。其次,复制的属性不再是 getter,而是具有原子值的普通属性(不是函数)。

使用 Object.assign 时执行的几乎相同的过程可能会更好地理解该行为:

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

如果你希望 wrapper getter 以新对象作为 this 被调用,那么做:

"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 .这是众多想法之一,源自 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>

虽然这有效地提供了多重继承,但是从表达式派生的类的层次结构并不是高效代码的真正组成部分。

装饰器

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

"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>

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

关于Javascript:混入 setter/getter (对象传播),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47952284/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com