简体   繁体   English

我可以创建一个可供创建对象的每个属性使用的类方法吗?

[英]Can I create a class method usable by each property of an created object?

Can I create a method usable by each property of an object?我可以创建一个对象的每个属性都可以使用的方法吗?

class myClass {
    constructor() {
        this.a = 1;
        this.b = 2;
        this.c = 3;
    }
    raise(x) {
        this += x;              //I know this doesn't work. I want the raise function to use 
                                //the value of its caller and increase it by x
    };
}

What I want to achieve is being able to call the raise method on any object property via我想要实现的是能够通过调用任何对象属性上的 raise 方法

obj1 = new myClass();

obj1.a.raise(1);            //a = 2
obj1.b.raise(3);            //b = 5
obj1.c.raise(100);          //c = 103

So I want to be able to use this syntax: object.property.method()所以我希望能够使用这个语法:object.property.method()

I tried creating raise on the class constructor, the class prototype or the Object prototype.我尝试在类构造函数、类原型或对象原型上创建 raise。 I also couldn't find any mention of this elsewhere.我在其他地方也找不到任何提及。

It would be impossible for obj.a to return a number, while also being able to call obj.a.raise to modify it. obj.a不可能返回一个数字,同时也可以调用obj.a.raise来修改它。

If you're open to a small tweak, you could retrieve the value via a method called something like .get , while the underlying value is stored and reassigned in the _a property:如果您愿意进行一些小调整,您可以通过一种名为.get类的方法检索该值,而底层值存储并重新分配在_a属性中:

 class myClass { constructor() { this._a = 1; this.a = { raise: num => this._a += num, get: () => this._a }; } } const obj = new myClass(); obj.a.raise(1); //a = 2 console.log(obj.a.get());

Using ES6 you can do it easily.使用 ES6,您可以轻松完成。 You may not need complex solution!您可能不需要复杂的解决方案! Sample is given below.示例如下。

2nd Solution, to use composition.第二种解决方案,使用组合。

 class PriceList { constructor(price, amount) { this._price = price; this._amount = amount; } get price() { return this._price; } set price(p) { this._price += p; // validation could be checked here such as only allowing non numerical values } get amount() { return this._amount; } set amount(p) { this._amount += p; // validation could be checked here such as only allowing non numerical values } } const priceList = new PriceList(1, 10); console.log(priceList); // PriceList { _price: 1, _amount: 10 } priceList.amount = 10; priceList.price = 100; console.log(priceList); // PriceList { _price: 101, _amount: 20 } class Value { constructor(v) { this._val = v; } get val() { return this._val; } set(v) { this._val = v; } raise(m) { this._val += m; } } class PriceList2 { constructor(price, amount) { this.amount = new Value(amount); this.price = new Value(price); } } const priceList2 = new PriceList2(1, 10); console.log(priceList2); priceList2.amount.raise(10); priceList2.price.raise(100); console.log(priceList2.amount.val); // 20 console.log(priceList2.price.val); // 101 priceList2.amount.val = 1 priceList2.amount.raise(10); console.log(priceList2.amount.val); //30
 .as-console-row {color: blue!important}

For literally all answers (except this one), you need to run a function to get the value, here it's more simplified.对于字面上所有的答案(除了这个),您需要运行一个函数来获取值,这里更简化。

 class myClass { constructor() { this.a = new Number(1); this.b = new Number(2); this.c = new Number(3); for (let p in this) { this[p].raise = x => { let fn = this[p].raise; this[p] = new Number(x + this[p]); this[p].raise = fn; } } } } let m = new myClass(); maraise(15); maraise(15); // A = 1 + 15 + 15 = 31 mbraise(10); mbraise(20); // B = 2 + 10 + 20 = 32 mcraise(17); mcraise(13); // C = 3 + 17 + 13 = 33 console.log(ma + 1, mb + 1, mc + 1) // 32 33 34 // logging just ma, mb, mc will get you an object with a raise function // only in stack overflow (or maybe other fake consoles), but the browser // console will definitely work and give you a Number object

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM