Reputation: 1016
I´ve been reading into the ki.js source code and stumbled over a strange use of the call() function (See function i(a)
on GitHub). First, I simplified that i(a)
function for my purposes, now the function looks like this:
function ki(selector, arr) {
document.querySelectorAll(selector).forEach((el) => { arr.push.call(this, el); });
}
When I call my function like so: new ki(".test", []);
, I get the expected result - an object with the DOM objects and a prototype property copyied from the ki() function prototype.
But, when I just slightly change the ki() function to this: (removing the, in my opinion unnecessary call() function):
function ki(selector, arr) {
document.querySelectorAll(selector).forEach((el) => { arr.push(el); });
}
Executing new ki(".test", []);
will result in an object without any of the DOM objects, only with the prototype property inherited by the constructor.
This is what I don´t understand. Why is it necessary to manipulate the array.prototype.push() source code (replacing this
with this
in a different context)? Furthermore, will this code also work when used in strict mode?
Thanks for any help.
Upvotes: 1
Views: 99
Reputation: 12637
first arr.push(el)
can also be written as arr.push.call(arr, el)
. looks familiar?
But this
!== arr
in your code.
In that Code arr.push.call(...)
is used as a shorthand for Array.prototype.push.call(...)
. Another common way of writing this is [].push.call(...)
.
Sidenote: wait untill you get to code like Function.prototype.apply.call(...)
Upvotes: 1
Reputation: 36
If the ki function is used as a Constructor then the el objects are not pushed to the arr Array, but to the this value, which would be the created object
arr = new Array
arr2 = new Array
document.querySelectorAll('a').forEach((el) => { arr2.push.call(arr, el); })
Hope this helps
Upvotes: 1