美文网首页
The four types of common JavaScr

The four types of common JavaScr

作者: Arthur_6c78 | 来源:发表于2017-09-27 15:12 被阅读0次

    The four types of common JavaScript leaks

    1: Global variables

    function foo(arg) {

    bar = "some text";

    }

    function foo(arg) {

    window.bar = "some text";

    }

    In this example, leaking a simple string won't do much harm, but it could certainly be worse.

    Another way in which an accidental global variable can be created is through this:

    function foo() {

    this.var1 = "potential accidental global";

    }

    // Foo called on its own, this points to the global object (window)

    // rather than being undefined.

    foo();

    To prevent these mistakes from happening, add 'use strict'; at the beginning of your JavaScript files. This enables a stricter mode of parsing JavaScript that prevents accidental global variables. Learn more about this mode of JavaScript execution.

    If you must use a global variable to store lots of data, make sure to assign it as null or reassign it after you are done with it.

    2: Timers or callbacks that are forgotten

    to explicitly remove these observers before the object is disposed of. For instance:

    var element = document.getElementById('launch-button');

    var counter = 0;

    function onClick(event) {

    counter++;

    element.innerHtml = 'text ' + counter;

    }

    element.addEventListener('click', onClick);

    // Do stuff

    element.removeEventListener('click', onClick);

    element.parentNode.removeChild(element);

    // Now when element goes out of scope,

    // both element and onClick will be collected even in old browsers // that don't handle cycles well.

    Nowadays, modern browsers (including Internet Explorer and Microsoft Edge) use modern garbage collection algorithms that can detect these cycles and deal with them correctly

    Frameworks and libraries such as jQuery do remove listeners before disposing of a node (when using their specific APIs for that). This is handled internally by the libraries which also make sure that no leaks are produced

    3.Closures

    var theThing = null;

    var replaceThing = function () {

    var originalThing = theThing;

    var unused = function () {

    if (originalThing) // a reference to 'originalThing'

    console.log("hi");

    };

    theThing = {

    longStr: new Array(1000000).join('*'),

    someMethod: function () {

    console.log("message");

    }

    };

    };

    setInterval(replaceThing, 1000);

    This snippet does one thing: every time replaceThing is called, theThing gets a new object which contains a big array and a new closure (someMethod). At the same time, the variable unused holds a closure that has a reference to originalThing (theThing from the previous call to replaceThing). Already somewhat confusing, huh? The important thing is that once a scope is created for closures that are in the same parent scope, that scope is shared.

    In this case, the scope created for the closure someMethod is shared with unused. unused has a reference to originalThing. Even though unused is never used, someMethod can be used through theThing outside of the scope of replaceThing (e.g. somewhere globally). And as someMethod shares the closure scope with unused, the reference unused has to originalThing forces it to stay active (the whole shared scope between the two closures). This prevents its collection.

    When this snippet is run repeatedly a steady increase in memory usage can be observed. This does not get smaller when the GC runs. In essence, a linked list of closures is created (with its root in the form of the theThing variable), and each of these closures' scopes carries an indirect reference to the big array, resulting in a sizable leak.

    4: Out of DOM references

    var elements = {

    button: document.getElementById('button'),

    image: document.getElementById('image')

    };

    function doStuff() {

    elements.image.src = 'http://example.com/image_name.png';

    }

    function removeImage() {

    // The image is a direct child of the body element.

    document.body.removeChild(document.getElementById('image'));

    // At this point, we still have a reference to #button in the

    //global elements object. In other words, the button element is

    //still in memory and cannot be collected by the GC.

    }

    相关文章

      网友评论

          本文标题:The four types of common JavaScr

          本文链接:https://www.haomeiwen.com/subject/fzruextx.html