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.
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.
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.