如何将函数绑定到从类方法返回的对象

How to bind a function to an object that is returned from a class method

提问人:Collaptic 提问时间:12/19/2022 更新时间:12/19/2022 访问量:280

问:

标题的措辞可能很糟糕,但我不确定如何表达我在这里想做什么。

从本质上讲,我所拥有的是一个包含两种方法的类:

  1. 一个对象工厂类函数,该函数返回一个对象,该对象包含三个属性(value1,value2,value3)和另一个绑定到该对象的函数。J.F.objFactorymyObj = {value1: 1, value2: 2, value2: 3, func()}
  2. 另一个类函数,它将根据 的输入值创建值 1-3。changeValuePropertiesmyObj

用户调用工厂方法并返回一个对象。目的是用户不会直接在返回的对象中修改值 1-3,而是调用内置方法来计算这些值并在对象上为用户更新这些值。即 假设最终用户是一个黑匣子,他们不知道如何为自己计算 value1、value2、value3。changeValueProperties

这里的主要问题是“this”关键字。“this”指的是 MyTestClass,当我真的希望它绑定到返回的对象时,以便可以修改其内部属性。我想这样的事情可以通过 call/apply/bind 方法实现,但我不太清楚如何在这种特定上下文中实现这一点。特别是当该方法将使用类自己的方法之一进行计算时。updateValues

我也愿意接受架构方面的替代建议。我意识到这可能不是犹太洁食,可能有更好的方法来实施我想要的策略。

class MyTestClass {
    dummyData;
    constructor() {
        this.dummyData = 100;
    }
    changeValueProperties(value) {
        return {
            value1: value*1,
            value2: value*2,
            value3: value*3
        }
    }



    objFactory(value, ..other parameters) {
        
        let computedValues = this.changeValueProperties(value);

        let updateValues = (newValue) => {
            let computedValues = this.changeValueProperties(newValue);
            // This is where updateValues needs to update
            // values 1-3 in myReturnedObj that has been returned to the calling user.
            // this keyword can't be used, because it is bound to MyTestClass and not
            // myReturnObj
            this.value1 = computedValues.value1;
            this.value2 = computedValues.value2;
            this.value3 = computedValues.value3;

        }

        let myReturnObj = {
            value1: computedValues.value1,
            value2: computedValues.value2,
            value3: computedValues.value3,
            updateValues: updateValues
        }
        return myReturnObj
    }

}

const myClass = new MyTestClass();

let myObj = myClass.objFactory(10,...other parameters for object generation); 
// {value1: 10, value2: 20, value3: 30, ...}
myObj.updateValues(20); 
// should return {value1: 20, value2: 40, value3: 60, ...}
JavaScript TypeScript 绑定

评论

0赞 Bergi 12/19/2022
我不太明白你为什么不让类实例返回对象?看来,并且有同样的责任。objFactoryMyTestClass.changeValuePropertiesmyReturnObj.updateValues

答:

0赞 beautifulcoder 12/19/2022 #1

这里发生了很多事情,首先,我认为箭头函数没有按照你想要的方式绑定。我建议改用。thisfunction

function updateValues(newValue) { /* ... */ }

评论

0赞 Collaptic 12/19/2022
感谢您指出,this 关键字对箭头函数的操作与普通函数的操作不同。仅使用普通的旧函数就是一个很好的解决方案。经过一番挖掘,我也能够使用箭头函数解决这个问题。我把它作为这篇文章的后续发布。
0赞 Collaptic 12/19/2022 #2

因此,在 beautifulcoder 指出其行为方式与正常函数不同之后,我最终解决了这个问题。但是,如果您固执己见并希望使用箭头函数解决问题,则可以使用以下重构代码:this

objFactory(value, ..other parameters) {
        
    let computedValues = this.changeValueProperties(value);

    let myReturnObj = {
        value1: computedValues.value1,
        value2: computedValues.value2,
        value3: computedValues.value3,
        updateValues: (newValue) => {
            let computedValues = this.changeValueProperties(newValue);
            myReturnObj.value1 = computedValues.value1;
            myReturnObj.value2 = computedValues.value2;
            myReturnObj.value3 = computedValues.value3;
        }
    }
    return myReturnObj
}

您可以在对象本身中引用对象定义。

1赞 Bergi 12/19/2022 #3

您似乎想引用两个不同的对象。您必须决定其中之一,或者两者都不决定。thisupdateValues

要不使用任何一个,请通过变量引用对象:

objFactory(value) {
    const computedValues = this.changeValueProperties(value);
    const myTest = this;
    const myReturnObj = {
        ...computedValues,
        updateValues(newValue) {
            const newComputedValues = myTest.changeValueProperties(newValue);
//                                    ^^^^^^
            Object.assign(myReturnObj, newComputedValues);
//                        ^^^^^^^^^^^
    };
    return myReturnObj;
}

这使用旧模式 [1][2][3]。var self = this

现在,您可以

  • 创建一个用于引用 :updateValuesthismyReturnObj

    objFactory(value) {
        const computedValues = this.changeValueProperties(value);
        const myTest = this;
        return {
            ...computedValues,
            updateValues(newValue) {
                const newComputedValues = myTest.changeValueProperties(newValue);
                Object.assign(this, newComputedValues);
    //                        ^^^^
        };
    }
    
  • 或者创建一个箭头函数,以便它从其父范围使用:updateValuethis

    objFactory(value) {
        const computedValues = this.changeValueProperties(value);
        const myReturnObj = {
            ...computedValues,
            updateValues: (newValue) => {
                const newComputedValues = this.changeValueProperties(newValue);
    //                                    ^^^^
                Object.assign(myReturnObj, newComputedValues);
        };
        return myReturnObj;
    }
    

评论

0赞 Collaptic 12/19/2022
这两个都是非常好的建议。