How is the console.log(something); working here?
It isn't. It never gets called because we don't ever testFn();, we just stringify (testFn) and send as plaintext.
It was just some sample code inside the function, could be anything inside there.
Plus, the information is NOT printed to the console.log either. How does that magic occur?
Again, the function is never called. That was just some sample code.
I see the .append is calling the function which includes the console.log,
See the lack of ()? It's NOT being called. It's being passed. Same as how callbacks work.
If I were to:
function testFn() {
console.log(test);
}
function testTest(something) {
}
testTest(testFn);
TestFN never runs, it's being passed by reference to testTest but it is never explicitly (); IF we change testTest to:
function testTest(something) {
something();
}
NOW it would be run.
But what is a Document and DocumentFragment at the end of the anonymous function?
And are all there parameters required to be defined to function correctly?
Pay VERY close attention to the code. See how the three Objects are passed in an array?
}([Element, Document, DocumentFragment]);
See the [], so it's an Array of those three objects.
(function(targetObjects) {
for (var i = 0, target; target = targetObjects[i]; i++) {
Which is then looped through. In the first loop target === Element, on the second loop it === Document, and on the third it === DocumentFragment. Also pay attention to the upper-case first letter. "Document" is the master class of which "document" (all lower case) is an instance.
.append is supposed to exists on all three ".prototype", so it is applied to all three objects.
Hence also the check for
if (target.hasOwnProperty('append')) continue;
Which is also run against all three. That way we don't try to overwrite it if it already exists.
And are all there parameters required to be defined to function correctly?
They are required if you want to document.append or documentFragment.append. Neither inherits from Element, but are supposed to support this function.
Would it apply to a document.body.append(Something) the same way it appears to modify the <code> element via the ID?
Document.body is the BODY tag and therefor an Element, so yes it works there.
document.append is ... strange, there is no real reason for it to exist, DocumentFragment on the other hand does exist, but it too is something I've never seen a point to having/using/existing since you can just work off an Element. They exist as methods in the specification though so if you're gonna write a polyfill you should at least TRY to match the spec 100%.
As you were confused by how the parameters were handled, I assume you're not familiar with "for by result"?
var anchors = document.getElementsByTagName('a');
for (var i = 0, a; a = anchors[i]; i++) {
// do something with each anchor here
}
So long as the members of an array-like -- such as a NodeList -- are "loose true" the above loop can assign the local VAR "a" to each anchor in the node list. If it's a valid node it's true and the loop keeps going, whilst if it's loose false -- like undefined -- we can stop looping as it didn't exist.
This is actually the fastest way across all browsers to loop through an array. It's faster than a normal "for" and makes Array.forEach look like it's standing still.
Same goes for if you had a normal array of values, we can evaluate the assignment.
var test = [0, false, ''];
for (var i = 0, value; 'undefined' === typeof (value = test[i]); i++) {
console.log(i, ' === "', value, '");
}
The only way value could end up undefined is if it's "out of range" of the array. Screwy as it is, this actually seems to break even on speed with the length compare:
var test = [0, false, ''];
for (var i = 0, iLen = test.length; i < iLen; i++) {
console.log(i, '==="', test[i], '"');
}
IF there's only one use of the value. However, if value is used multiple times, it gets faster and faster and faster, even compared to just flat doing an assignment inside the loop.
It's a shame that client-side "for/of" isn't real world deployable yet, and there's still no operation that returns both key and value without resorting to the overhead of callbacks.
In hindsight, I probably should have written that function as:
(function() {
for (var i = 0, target; target = arguments[i]; i++) {
if (target.hasOwnProperty('append')) continue;
Object.defineProperty(target.prototype, 'append', {
value : function() {
for (var i = 0, item; 'undefined' !== typeof (item = arguments[i]); i++) {
this.appendChild(
item instanceof Node ? item : document.createTextNode(String(item))
);
}
}
});
}
}(Element, Document, DocumentFragment);
Since JS makes a perfectly good arguments array-like we can work from.
-- edit -- oh and excuse you must occasional use of Yodish expressions I have. Hrrm? gzip compress better do they, so minification such as closure it does. Write that way from start why not?
Joking aside a lot of these dipshit "Linters" will throw a conniption fit over the presence of "yodish" expressions, where the static is before a variable. It's utter pedantic BS on their part and another of the reasons that by the time I make a "linter" stop bitching about BS, they no longer do anything of value. There's NOTHING wrong with putting the static before a value, it often in larger codebases results in smaller gzip compression (damned if I know why) hence why things like Google's "Closure Compiler" or other such minification software will actually switch your evaluations to using it!