简体   繁体   中英

Callback function cannot access variable within parent function's scope

In the below code, variable text is not accessible in the findTextToDelete function (it generates an error)

 array = ['a', 'b', 'removeThis', 'c']; removeText("removeThis"); function removeText(text) { array.splice(array.findIndex(findTextToDelete),1); } function findTextToDelete(element) { return element === text; } 

I am able to get around this by creating a global variable 'globalText':

 var globalText = ""; array = ['a', 'b', 'removeThis', 'c']; removeText("removeThis"); function removeText(text) { globalText = text; array.splice(array.findIndex(findTextToDelete),1); } function findTextToDelete(element) { return element === globalText; } console.log(array) 

However I am trying to understand why the first method does not work.

It seems there must be a better way to do this. Is there a way to pass 'text' into the callback function?

Any help would be appreciated.

You could use a closure over text for finding the element.

 function removeText(text) { array.splice(array.findIndex(findTextToDelete(text)), 1); } function findTextToDelete(text) { return function (element) { return element === text; } } var array = ['a', 'b', 'removeThis', 'c']; removeText("removeThis"); console.log(array) 

Yes, I think you are confused with closure .

Callback function doesn't have caller's scope. So you can't access the variable text in findTextToDelete .

If you want to access the variable, pass it to the callback function as an argument.

Locals defined in one function are only available to other functions that are defined within the first function. The scope of locals defined in a function is limited to that function. This is generally known as lexical scoping . (Other languages have different rules, but lexical is common in imperative languages.)

So you need to define a function inside removeText to access text .

One way is to just use a function literal rather than a named function:

function removeText(text) {
    globalText = text;
    array.splice(array.findIndex(function (element) {
        return element === globalText;
    }, 1);
}

Another way is to forward the extra value:

function removeText(text) {
    globalText = text;
    array.splice(array.findIndex(function (el) { returnfindTextToDelete(el, text); }, 1);
}

function findTextToDelete(element, text) {
    return element === globalText;
}

(If you're not stuck with backward compatibility then arrow functions make both easier to write.)

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