0

In the code below I would like to pass a reference to a function that resides on the parent scope to the nested scope of the function "nested", so I can call the function on the parent scope from the nested function. I tried passing it in as a parameter but it doesn't work. I'm just learning/messing around with nested closures and wondering if this could be done.

I would like to have the syntax for calling nested be: callme.nested()

var obj = function(val){
var access = val;
var apex = 0;
return {
    callme : (function(siblyng){
        var privatevar = 2;
        return {
            nested : function(){
                privatevar++;
                apex = privatevar;
                return access + " " + privatevar + " " + siblyng("child");
            }
        }
    })(this.sibling),
    assess : function(){
        return apex + " " + this.sibling("parent");
    },
    sibling : function(val){
        return "returned from " + val + " scope";
    }
}
}
var objref = obj(true);
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.assess());
console.log(objref.sibling('global'));
  • 2
    "*pass a reference to a function residing on the parent scope to the nested scope of the function nested*". Please clarify which is the reference, which is the residing function, which is the parent scope, which is the nested scope, and which is the function nested. – Oriol Apr 21 '16 at 16:41
  • i guess the closest to get from the terms "function nesting & closures" are higher order functions. these are functions that return (and generate) other functions http://eloquentjavascript.net/05_higher_order.html Nesting in terms of returning nested / self-referencing data will most likely just create a mess. – lipp Apr 21 '16 at 16:56
  • @Oriol, I updated my question, what I would like to do is call the function 'sibling' from the nested function 'nested'. However, I have tried two different ways to pass in a reference to the function and neither worked. – user2912840 Apr 21 '16 at 18:02
  • @lipp, thanks for the link! – user2912840 Apr 21 '16 at 18:18

2 Answers2

0

If I understood you well, you can do it like so

var obj = function(val){
var access = val;
var apex = 0;
var ret;
return (ret = {
    callme : function() {
        var privatevar = 2;
        return {
            nested : function(){
                privatevar++;
                apex = privatevar;
                return access + " " + privatevar + " " + ret.sibling("child");
            }
        };
    }(),
    assess : function(){
        return apex + " " + this.sibling("parent");
    },
    sibling : function(val){
        return "returned from " + val + " scope";
    }
  });
};

var objref = obj(true);
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.callme.nested());
console.log(objref.assess());
console.log(objref.sibling('global'));
Jakub Rożek
  • 2,110
  • 11
  • 12
  • please clarify where is fix? – Alex Filatov Apr 21 '16 at 16:49
  • var privatevar = 2, siblyng = this.sibling; // here You could use arrow functions aswell (but that's feature one of the ES 2015 standards and therefore it's not supported in older browsers, so you would have to use transpilers like Babel or Traceur). – Jakub Rożek Apr 21 '16 at 16:57
  • You can set a [getter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) to make it work like you described. So you would have to write 'get callme() {' instead of 'callme : function() {' – Jakub Rożek Apr 21 '16 at 18:13
  • @P0lip,I just realized that your answer does not work as `privatevar` is no longer saved in a closure, so it does not iterate on multiple calls to `nested`, it is overwritten each time. Even when using a getter. – user2912840 Apr 21 '16 at 18:45
  • @user2912840 was my bad indeed. I've just updated the code. Unfortunately we must hold a reference to the returned object. Hope it works now as expected. BTW, don't make so nested closures when they are redundant. – Jakub Rożek Apr 21 '16 at 18:55
  • Thanks P0lip. Only problem is now it's not nested closures but nested objects. Is that true? btw, what books have you read on JS? – user2912840 Apr 21 '16 at 19:03
  • Actually the closure is the local variables that persist when the function returned, so in your code you can say it's a closure, because the variables are kept. More about that [here](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1) When it comes to learning, I really advise you to complete [these](https://developer.mozilla.org/en-US/docs/Web/JavaScript) tutorials. They are awesome and relevant. What about books? Well, I didn't read many books, but the best I read were [this](http://speakingjs.com/) and [this](http://exploringjs.com/) - read in order I provided. – Jakub Rożek Apr 21 '16 at 19:15
0

Your this in the following code was pointing to the global Window object and so it was not able to find the method. You could have directly called this.sibling in your nested method without the need of passing it.

callme : (function(siblyng){
    var privatevar = 2;
    return {
        nested : function(){
            privatevar++;
            apex = privatevar;
            return access + " " + privatevar + " " + siblyng("child");
        }
    }
})(this.sibling),
Bhabishya Kumar
  • 731
  • 3
  • 7