Javascript's equivalent of destruct in object model

后端 未结 3 1234
走了就别回头了
走了就别回头了 2020-12-17 07:21

Since I\'ve dealt in the past with javascript\'s funky \"object model\", I assume there is no such thing as a destructor. My searches were mildly unsuccessful, so you guys a

相关标签:
3条回答
  • 2020-12-17 07:59

    MDN is a nice resource for JS. No, there is nothing like calling a function when an object ceases.

    0 讨论(0)
  • 2020-12-17 08:04

    In other languages the destructor is handy for implementing the memento pattern. That's actually what lead me to this topic. For example, in a click event it'd be nice to have a generic function that I can pass the event target to that disables the target and then re-enables it when it falls out of scope. Consider a submit button that does something like this:

    function async saveMyStuff(e) {
        const sleeper = new nap(e)
        let data = await fetch(...)
        // a bunch more code.
    }
    
    class nap {
        constructor(e) {
          this.button = e.currentTarget
          this.button.disabled = true
        }
        destructor() { this.button.enabled = true }
    

    }

    This kind of construct would give me a oneliner that handles enabling/disabling all of my buttons when I'm talking to the backend or doing any other processing. I don't have to worry about cleaning up if I return somewhere in the middle or anything like that.

    0 讨论(0)
  • 2020-12-17 08:16

    As of more recently, this link is of more use to answer this question. The most important part:

    As of 2012, all modern browsers ship a mark-and-sweep garbage-collector.

    ...

    Cycles are no longer a problem

    In the first example above, after the function call returns, the two objects are no longer referenced by any resource that is reachable from the global object. Consequently, they will be found unreachable by the garbage collector and have their allocated memory reclaimed.

    Limitation: Releasing memory manually

    There are times when it would be convenient to manually decide when and what memory is released. In order to release the memory of an object, it needs to be made explicitly unreachable.

    So as far as cyclic references goes, de[con]structors aren't really needed.


    One cool trick I have thought of though, if you have cyclic references and you want easy manual control over deconstruction...

    class Container {
      constructor() {
        this.thisRef = [ this ];
        this.containee = new Containee({ containerRef: this.thisRef });
      }
    
      //Note: deconstructor is not an actual JS thing/keyword.
      deconstructor() {
        //Have to delete `this.thisRef[0]` and not `this.thisRef`, in
        //order to ensure Containee's reference to Container is removed.
        delete this.thisRef[0];
      }
    
      doSomething() {
    
      }
    }
    
    class Containee {
      constructor({ containerRef }) {
        //Assumption here is, if the Container is destroyed, so will the Containee be
        //destroyed. No need to delete containerRef, no need for a
        //deconstructor function!
        this.containerRef = containerRef;
      }
    
      someFunc() {
        this.containerRef[0].doSomething();
      }
    }
    
    let c = new Container();
    ...
    //No cyclic references!
    c.deconstructor();
    

    So here, instead of the Containee class storing a direct reference to the Container instance, it stores a reference to a size 1 array containing the Container reference, which the Container instance itself can then delete itself from. The array, with the reference, is managed by Container.

    But again, this isn't really needed, since garbage collection in all modern browsers is mark-and-sweep and can handle cyclic references.

    0 讨论(0)
提交回复
热议问题