【问题标题】:JavaScript instances of a class类的 JavaScript 实例
【发布时间】:2013-10-04 14:39:19
【问题描述】:

假设我有一个函数:

function Control(value){
    var self=this;
    self.param1=value;
    self.param2=value.text;
}

是否可以在 JavaScript 中获取该函数创建的所有实例?

【问题讨论】:

  • 我能想到的唯一简单的方法是将任何创建的Control 类的引用存储在某个全局数组中。您将在 Control 构造函数(上面的函数)中进行存储
  • 据我所知,没有这样的东西。您需要有自己的机制来保存 Control 类的所有实例。
  • 不(不自己跟踪它们)。否则,垃圾收集器不可能存在。
  • 另请注意,JavaScript 中没有类。

标签: javascript


【解决方案1】:

如果不修改类,您几乎无能为力。如果您可以修改它,只需保留您构造的每个实例的引用即可:

function Control(value){
    Control.instances = Control.instances || [];
    Control.instances.push(this);

    var self=this;
    self.param1=value;
    self.param2=value.text;
}

// In case you are worried about garbage collection
Control.prototype.destroy = function() {
    var index = Control.instances.indexOf(this);
    Control.instances.splice(index, 1);
}


// Usage:
var x = new Control();
var y = new Control();
// do stuff with x and y
console.log('There are ' + Control.instances.length + ' instances of Control');
// all done with x and y
x.destroy();
x = null;
y.destroy();
y = null;
// no more references to the two instances, they can be garbage collected

但请注意,您将阻止垃圾收集器释放您未调用 destroy() 的任何实例的内存。

【讨论】:

    【解决方案2】:

    我在我的一个项目中使用了类似的东西,因为我需要为所有实例调用一个方法...

    function Person(firstname, lastname) {
        var self = this; // For reference to "this" 
        this.firstname = firstname;
        this.lastname = lastname;
    
    
        document.addEventListener( "event/person", function( event ) {
            var params = event.detail.params;
            Person.prototype[ params.method ].call(self);
    
           // Take params:   params.params => ["param1", "param2", "param3"]
        });
    }
    
    
    Person.prototype.toString = function() {
        console.log("Firstname: " + this.firstname + " Lastname: " + this.lastname);  
    };
    
    
    Person.prototype.callAll = function( params ) {
        document.dispatchEvent( new CustomEvent( "event/person", {
            detail: {
                "params": params   
            }
        }));
    };
    
    
    var a = new Person("Gabriel", "Gatu");
    var b = new Person("Marco", "Giovannini");
    
    
    Person.prototype.callAll({
        method: "toString",
        params: ["param1", "param2", "param3"]
    });
    

    它使用侦听器在简单方法和构造函数类之间进行通信,还允许您调用类原型中包含的任何方法,必要时传递参数...

    附言抱歉英语不好... :)

    【讨论】:

    • Person.prototype[ params.method ].call(self); = self[params.method]() 当您的实例超出范围时,事件侦听器仍然存在。
    【解决方案3】:

    只需将其存储在全局数组中即可。类似于一些静态模式。

    var controls = [] ; //Global array
    
    function Control(value){
        var self = this;
        self.param1=value;
        self.param2=value.text;
    
       controls.push(self);
    }
    

    【讨论】:

      【解决方案4】:

      正如@Ian 在他的评论中建议的那样,您可以这样做:

      // global are bad though!
      var controlInstances = [];
      
      function Control(value){
          // track instances
          controlInstances.push(this)
          this.param1 = value;
          thsi.param2 = value.text;
      }
      

      【讨论】:

        【解决方案5】:

        我在我的一个项目中使用了类似的东西,因为我需要为所有实例调用一个方法...

        function Person(firstname, lastname) {
            var self = this; // For reference to "this" 
            this.firstname = firstname;
            this.lastname = lastname;
        
        
            document.addEventListener( "event/person", function( event ) {
                var params = event.detail.params;
                Person.prototype[ params.method ].call(self);
        
               // Take params:   params.params => ["param1", "param2", "param3"]
            });
        }
        
        
        Person.prototype.toString = function() {
            console.log("Firstname: " + this.firstname + " Lastname: " + this.lastname);  
        };
        
        
        Person.prototype.callAll = function( params ) {
            document.dispatchEvent( new CustomEvent( "event/person", {
                detail: {
                    "params": params   
                }
            }));
        };
        
        
        var a = new Person("Gabriel", "Gatu");
        var b = new Person("Marco", "Giovannini");
        
        
        Person.prototype.callAll({
            method: "toString",
            params: ["param1", "param2", "param3"]
        });
        

        它使用侦听器在简单方法和构造函数类之间进行通信,还允许您调用类原型中包含的任何方法,必要时传递参数...

        附言抱歉英语不好... :) 再见!

        【讨论】:

        • 如果您担心垃圾收集器,我认为您必须简单地将 destroy 方法添加到类原型并将侦听器与该对象分离。你怎么看?
        【解决方案6】:

        没有。

        您只能触摸已明确引用的对象这一事实是part of JavaScript security model*。

        *该安全模型不适用于 JavaScript 中的全局对象。

        【讨论】:

          【解决方案7】:
          var foo = new Control('bar');
          console.log(foo.param1);
          

          【讨论】:

          • 这与问题有什么关系?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-21
          • 2017-04-01
          • 2020-04-28
          • 1970-01-01
          • 1970-01-01
          • 2022-06-29
          相关资源
          最近更新 更多