How to Call a Func Within a Closure

javascript: access function in closure

Variables and functions declared in the current lexical scope cannot be accessed by name using [] syntax - only property keys (per your second example) can be looked up dynamically based on the contents of another variable.

The only way around this is to resort to eval, which is almost never a good idea.

An exception applies for variables and functions declared in the global scope - those are actually properties of window.

Calling a parent function inside a closure

The reason why is that this in the callback function will typically refer to the global window scope.

this is a common source of pain in JS developers and more often than not it doesn't refer to what you think it may. You can search the full details online.

Why not closure it like this?

function Thing(request, response) {

this.foo = function() {
console.log("this is foo");
}

this.doThing = function() {
var self = this; //Closure to the Thing function
// Get SOAP args
args = { foo: this.request.cookies.foo };
// From the SOAP npm package library
soap.createClient(function(err, client) {
client.doSomething(args, function(err, result) {
self.foo();
});
});
}
}

How To Call a func within a Closure

To handle this situation you have multiple option.

  1. Create delegate/protocol with your Location class

    • Create one protocol and implement that protocol method with your ViewController and declare its instance in your Location class. After then in the completionHandler of reverseGeocodeLocation call this delegate method. Check Apple documentation on Protocol for more details.
  2. You can create completionHandler with your getLocationName method of Location class.

    • Add completionHandler with getLocationName and called that completionHandler inside the completionHandler of reverseGeocodeLocation like this way.

      func getLocationName(completionHandler: @escaping (_ success: Bool) -> Void) {

      let geoCoder = CLGeocoder()
      let location = CLLocation(latitude: currentLatitude, longitude: currentLongitude)

      geoCoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in
      guard let addressDict = placemarks?[0].addressDictionary else {
      completionHandler(false)
      return
      }
      if let city = addressDict["City"] as? String {
      self.currentCity = city
      print(city)
      }
      if let zip = addressDict["ZIP"] as? String {
      print(zip)
      }
      if let country = addressDict["Country"] as? String {
      print(country)
      }
      completionHandler(true)
      //self.nowUpdateUI()
      })
      }

      Now in ViewController where you are calling this function call your updateUI method inside the completion block.

      Location.sharedInstance.getLocationName { (success) in
      if success {//If successfully got response
      self.updateUI()
      }
      }
  3. You can add observer for (NS)NotificationCenter.

    • Register the observer with (NS)NotificationCenter and then post the notification inside the completionHandler of reverseGeocodeLocation. You can get more detail on this with this StackOverflow Post.

Calling a function within a closure in python

In the absence of lambda I might look into functools.partial. If that isn't allowed, you could probably do:

import threading
def func1(a,b):
def func2():
def func4():
return func3(a,b)
return threading.Thread(target=func4)
return func2

func2=func1(a,b)
func2()

call a function in a closure using call or apply?

If Process is in the global scope, you can walk the tree to get the reference to the method so you can execute it.

var Process = (function(Process, $) {

_thing1 = function(a, b, c) {

return a + b + c;

}

_thing2 = function(a, b, c) {

return $(a).html(b + c);

}

return {

Fred: {

Add: _thing1

},

Bob: {

Add: _thing2

}

}

}(Process || {}, jQuery));

var data = {

"function": "Process.Fred.Add",

"params": [1, 2, 3]

}

var result = data.function.split(/\./g) //break up string into pieces

.reduce((o, k) => o[k], window) //walk the tree to get method reference

.apply(this, data.params); //execute the method with the parameters

console.log(result)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

javascript, about closure function call

The reason you are getting 123 all the time is because every time you click on the button, you take a new inner function with a closure on counter variable with value 0; So value of counter always remains 0 and when you add 123 to 0 you get 123.
If you move closure part out of the event handler, you would get exact same result as in the first case.

Notice the line var inner = add(); //<---Notice this line. This would take the closure one time and subsequently you will keep increasing the value of counter.

Also, notice this line inside myFunction:

document.getElementById("demo").innerHTML = inner.call(this, 123);

Here we are calling the inner function that we had reference on earlier.

/*var add = (function (test) {

var counter = 0;

return function (test) {return counter += test;}

})();*/

function add(test) {

var counter = 0;

return function(test) {

return counter += test;

}

}

var inner = add(); //<---Notice this line

function myFunction() {

//document.getElementById("demo").innerHTML = add(123);

document.getElementById("demo").innerHTML = inner.call(this, 123);

}

var btn = document.getElementById("btn");

btn.addEventListener("click", myFunction);
<p>Counting with a local variable.</p>

<button type="button" id="btn">Count!</button>

<p id="demo">0</p>

Trigger an event to call a function that's inside of a closure

You can define a variable var press; outside of WM, inside of WM, remove var before press and set press = function() {}. You should then be able to call press(down) at click of button

var press;

press = function(e) {
console.log(e);
// Mouse down location
var sizeHotspotStartX, toolIndex,
mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),
mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);

var elementPos = getElementPos(
document.getElementById(options.canvasElementId
|| 'canvasDiv')
);
mouseX -= elementPos.x;
mouseY -= elementPos.y;
announce(mouseX, mouseY);
};

jQuery(document).ready(function() {
jQuery('#buttonDiv').on('click', 'button', function() {
var down = jQuery.Event("mousedown", {
pageX: 50,
pageY: 50
});
press(down); // call `press` at `button` click
//jQuery('#canvasDiv canvas').trigger(down);
});
});

// based on http://www.williammalone.com/projects/html5-canvas-javascript-drawing-app-with-bucket-tool/

var press;

var WM = {};

WM.drawingApp = function(options) {

"use strict";

var canvas, context,

// Add mouse and touch event listeners to the canvas

createUserEvents = function() {

var getElementPos = function(element) {

var parentOffset, pos;

if (!element) {

pos = {

x: 0,

y: 0

};

} else {

pos = {

x: element.offsetLeft,

y: element.offsetTop

};

if (element.offsetParent) {

parentOffset = getElementPos(element.offsetParent);

pos.x += parentOffset.x;

pos.y += parentOffset.y;

}

}

return pos;

};

press = function(e) {

console.log(e)

// Mouse down location

var sizeHotspotStartX, toolIndex,

mouseX = (e.changedTouches ? e.changedTouches[0].pageX : e.pageX),

mouseY = (e.changedTouches ? e.changedTouches[0].pageY : e.pageY);

var elementPos = getElementPos(document.getElementById(options.canvasElementId || 'canvasDiv'));

mouseX -= elementPos.x;

mouseY -= elementPos.y;

announce(mouseX, mouseY);

};

var announce = function(x,y) { alert('press at: ' + x + ', ' + y); }

// Add mouse event listeners to canvas element

canvas.addEventListener("mousedown", press, false);

},

// Creates a canvas element, loads images, adds events, and draws the canvas for the first time.

init = function() {

// Create the canvas (Neccessary for IE because it doesn't know what a canvas element is)

canvas = document.createElement('canvas');

canvas.setAttribute('width', 100);

canvas.setAttribute('height', 100);

canvas.setAttribute('id', 'canvas');

document.getElementById(options.canvasElementId || 'canvasDiv').appendChild(canvas);

context = canvas.getContext("2d"); // Grab the 2d canvas context

createUserEvents();

};

init();

return {};

};

jQuery(document).ready(function() {

jQuery('#buttonDiv').on('click', 'button', function() {

var down = jQuery.Event("mousedown", {

pageX: 50,

pageY: 50

});

press(down)

//jQuery('#canvasDiv canvas').trigger(down);

});

});

var drawingApp = WM.drawingApp({

canvasElementId: "canvasDiv"

});
 #canvasDiv canvas {

border: solid black 1px;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">

</script>

<div id="canvasDiv"></div>

<div id="buttonDiv">

<button>why can't I send a click to the canvas?</button>

</div>


Related Topics



Leave a reply



Submit