简体   繁体   中英

How function reference works in js?

Recently I've been trying to use pixi.js for some fun project and I come across a concept that I do not understand at all. Quoting some code:

PIXI.loader
.add([
"images/one.png",
"images/two.png",
"images/three.png"
])
.on("progress", loadProgressHandler)
.load(setup);

function loadProgressHandler(loader, resource) {
console.log(`loading: ${resource.url}`);
};

How these arguments (loader, resource) are passed to the function since we only pass the reference to it in the event listener? Can someone show a generic implementation beneath that concept?

Arguments are passed to the function when it is called.

The code which calls that function isn't in the question. It is done somewhere behind the on function.

In short: The same way as normal, you just aren't looking at the point where it happens.

 const show = value => console.log(value); const call_callback_with_hello_world = callback => callback("Hello, world"); call_callback_with_hello_world(show); 

Lets say we have a function called callMe that just prints a number that its given:

function callMe(number) {
    console.log(`I'm number: ${number}`);
}
callMe(2);

We can create a new variable to that same function, and call the newly created variable. This is possible since it's pointing to the same function that we've created earlier.

const callMeAswell = callMe;
callMe(3);
callMeAswell(4);

In short, this is what's happing inside the PIXI loaders, except for that it's stored somewhere else for you. Lets create a class to store the numbers and the function that we want to call:

function SomeLoader(){
    this.numbers = []; // list of numbers we want to store for later usage
    this.func = null; // function that we want to call when we're done loading
}
SomeLoader.prototype.add = function(number) {
    this.numbers.push(number); // add the number to the list of numbers
}
SomeLoader.prototype.on = function(func) {
    this.func = func; // just store the function for now, but don't do anything with it
}
SomeLoader.prototype.pretendToLoad = function() {
    for(const number of this.numbers) {
        this.func(number); // now we're going to call the function that we've stored (callMe in the example below)
    }
}

const loader = new SomeLoader();
loader.add(5);
loader.add(6);
loader.on(callMe);
loader.pretendToLoad();

Or fluently:

function SomeLoader(){
    this.numbers = [];
    this.func = null;
}
SomeLoader.prototype.add = function(number) {
    this.numbers.push(number);
    return this;
}
SomeLoader.prototype.on = function(func) {
    this.func = func;
    return this;
}
SomeLoader.prototype.pretendToLoad = function() {
    for(const number of this.numbers) {
        this.func(number);
    }
}

new SomeLoader()
    .add(7)
    .add(8)
    .on(callMe)
    .pretendToLoad();

Looks almost the same as the PIXI loaders, doesn't it? :)

What @Quentin said is correct - adding on to that however...

A generic concept beneath that implemention is called a callback and would look like so:

 function Loop(callback, index){ callback(index); } function CallbackFunction(val){ console.log(val) } for(var i = 0; i < 5; i++){ Loop(CallbackFunction, i); } 

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