简体   繁体   中英

I don't understand a JavaScript code snippet

Hello I'm training making some assert suits libraries, but I have a big problem understanding the javascript behavior in a code section. here the code.

(function(){
    var results;
    this.assert = function(value, desc){
        var li = document.createElement('li');

        // I got two CSS classes "pass" and "fail"
        li.className = value ? 'pass' : 'fail';

        var txt = document.createTextNode(desc);

        li.appendChild(txt);
        results.appendChild(li);

        if(!value){
            li.parentNode.parentNode.className = 'fail';
        }
        return li;
    }
    this.test(name, fn){
        //I have an UL element with ID "results"
        results = document.getElementById('results');

        //but i will create another UL element
        var ul = document.createElement('ul');

        /*and here my trouble, I don't understand the sense of change
        the value of "results" variable, and why the reference to "results" ul element
        still serves, could you explain me that please?*/
        results = assert(true, name).appendChild(ul);
        fn();
    }
})();
//and here my library working
window.onload = function(){
    test('first test', function(){
        assert(2 + 2 == 4, 'True assertion');
    });
}

My big problem is understanding how does it work the change of variable "results".

From

//I have an UL element with ID "results"
results = document.getElementById('results');

To

results = assert(true, name).appendChild(ul);

I understand assert method creates a li element, but i don't understand why the reference to the results ul element still works. please explain me that.

是否要追加断言返回的li结果?

results = ul.appendChild(assert(true,name));

The line following immediately invoked function expression (IIFE):

(function(){
    var results;

creates a variable results within the function's execution context. This function:

   this.test(name, fn){
        //I have an UL element with ID "results"
        results = document.getElementById('results');

has that execution context on its scope chain. The relationship remains after the outer function finishes, creating a closure.

Therefore, each time you call test , it is accessing the same results variable.

I suggest you read more about IIFEs and closures.

NB

You can't append a UL to a UL as they can only have LI as element child nodes. Also, assuming that this within the IIFE is not sensible as in strict mode it will be undefined. To fix that, pass the global object to the IIFE and use it:

(function (global) {
    var results;

    global.assert = function(value, desc){

 ...

}(this));

results was declared inside the function as var results and Javascript uses block function scope so inside the block quote function where it's given a reference to the new ul that's been created inside of the function itself. You should read more on closures and execution context. This link should be of much help.

Closures

Each time the function is called, it creates a new execution context in which it is placed, the function is executed, the variable result is declared inside as private and then the same private variable is given a new reference inside the new block scope created and ul is appended to the results variable.

When results = assert(true, name).appendChild(document.createElement('ul')); is called, the results variable in the this.test() scope is updated and since this.assert() is returning a li element, ul is appended to the results(which now is document.getElementById('results')) hence giving a new ul inside of the li created by this.assert() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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