通过实例方法修改类的所有成员 [英] Modifying all members of a class via an instance method

查看:60
本文介绍了通过实例方法修改类的所有成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JavaScript中,是否可以在影响其所有兄弟节点的对象上调用实例方法?

In JavaScript, is it possible to call an instance method on an object that affects all of its siblings?

例如,假设我有以下类:

For example, say I have the following class:

function Thing() {
  this.active = false;
}

Thing.prototype = {
  constructor: Thing,

  activate: function() {
    this.active = true;
  },
  deactivate: function() {
    this.active = false;
  }
  
};

我可以创建一个 activateAll 可以激活类 Thing 的所有实例的方法?

Is it possible for me to create an activateAll method that can activate all of the instances of class Thing?

我需要 this.active 成为实例变量。

推荐答案

您可以将所有实例存储在一个数组中,并迭代它们以更改它们的 active 财产。但是,存储所有实例意味着它们不会被垃圾回收,因此您将浪费内存。如果数组变得庞大,迭代就会很慢。

You could store all the instances in an array, and iterate them to change their active property. However, storing all the instances means they won't be garbage collected, so you will waste memory. And if the array becomes huge, iterating it will be slow.

var Thing = (function() { // Use a closure to hide `instances`
  var instances = [];
  function Thing() {
    this.active = false;
    instances.push(this);
  }
  Thing.prototype.activate = function() {
    this.active = true;
  };
  Thing.prototype.activateAll = function() {
    instances.forEach(function(instance) {
      instance.active = true;
    });
  };
  return Thing;
})();

更好的方法是为每个实例定义公共默认活动和默认优先级,以及自己的活动和自己的优先级。然后,

A better way would be defining common default activity and default priority, and an own activity and an own priority for each instance. Then,


  • 要获取实例的活动,请比较默认优先级和自己的优先级。最大的决定是返回默认活动还是自己的活动。

  • 要设置实例的活动,请更新自己的活动。如果默认活动较大,请增加自己的优先级。

  • 要设置所有实例的活动,请更新默认活动并增加默认优先级。

var Thing = (function() {
    var defActive = false, /* default activity */
        defPriority = 0; /* default priority */
    /* `defPriority >= ownPriority` will always hold */
    function Thing() {
        var ownActive,
            ownPriority = -1;
        Object.defineProperty(this, 'active', {
            get: function() {
                return defPriority > ownPriority ? defActive : ownActive;
            },
            set: function(val) {
                ownActive = val;
                ownPriority = defPriority;
            }
        });
    }
    Thing.prototype.activate = function() {
        this.active = true;
    };
    Thing.prototype.activateAll = function() {
        defActive = true;
        ++defPriority;
    };
    return Thing;
})();

如果 activateAll 将被多次调用并且你不想不必要地增加 defPriority ,你可以添加一个布尔变量来知道某个属性是否达到了默认属性。

If activateAll will be called lots of times and you don't want to increase defPriority unnecessarily, you can add a boolean variable to know if some own property reached the default one.

var Thing = (function() {
  var defActive = false, /* default activity */
      defPriority = 0, /* default priority */
      someOwnPriorityReachedDefPriority = false;
  function Thing() {
    var ownActive,
        ownPriority = -1;
    Object.defineProperty(this, 'active', {
      get: function() {
        return defPriority > ownPriority ? defActive : ownActive;
      },
      set: function(val) {
        ownActive = val;
        ownPriority = defPriority;
        someOwnPriorityReachedDefPriority = true;
      }
    });
  }
  Thing.prototype.activate = function() {
    this.active = true;
  };
  Thing.prototype.activateAll = function() {
    defActive = true;
    if(someOwnPriorityReachedDefPriority) {
      ++defPriority;
      someOwnPriorityReachedDefPriority = false;
    }
  };
  return Thing;
})();

无论如何,请注意在原型中添加该方法没有多大意义。根据OOP原则,在变量中调用方法不应影响其他变量。相反,请考虑将该方法添加到构造函数本身。

In any case, note that adding that method in the prototype doesn't make much sense. According to the OOP principles, calling a method in a variable should not affect other variables. Instead, consider adding the method to the constructor itself.

一个完整的示例可能是这样的:

A full example could be like this:

var Thing = (function() {
  var defActive = false, /* default activity */
      defPriority = 0, /* default priority */
      someOwnPriorityReachedDefPriority = false;
  function Thing() {
    var ownActive,
        ownPriority = -1;
    Object.defineProperty(this, 'active', {
      get: function() {
        return defPriority > ownPriority ? defActive : ownActive;
      },
      set: function(val) {
        ownActive = val;
        ownPriority = defPriority;
        someOwnPriorityReachedDefPriority = true;
      }
    });
  }
  Thing.prototype.activate = function() {
    this.active = true;
  };
  Thing.prototype.deactivate = function() {
    this.active = false;
  };
  Object.defineProperty(Thing, 'activeAll', {
    set: function(val) {
      defActive = val;
      if(someOwnPriorityReachedDefPriority) {
        ++defPriority;
        someOwnPriorityReachedDefPriority = false;
      }
    }
  });
  Thing.activateAll = function() {
    Thing.activeAll = true;
  };
  Thing.deactivateAll = function() {
    Thing.activeAll = false;
  };
  return Thing;
})();

这篇关于通过实例方法修改类的所有成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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