Understanding the crockford function that returns a variable value function

I just watched the video by Douglas Crockford and he gave the following exercise:

write a function so that when you pass a variable, a function is returned that, if called, returns the value of the variable.

so I wrote the following function:

function funcky(o) {
    return function send(o){ // notice the o in send
      return o;
    }
  }

  var x = funcky(3);

  console.log(x()); // i get undefined why ?? 

      

pay attention to o

in the message. I've been programming javascript for a while, but I still don't understand why I'm getting undefined ??

The crockfords' solution was as follows:

  function funcky(o) {
    return function send(){
      return o;
    }
  }

  var x = funcky(3);

  console.log(x()); // get 3 now .

      

now how does this solution work and mine is wrong? I don't see much difference in my solution and nothing is clearly not the way I see it. Can someone explain please?

+3


source to share


4 answers


It has to do with volume o

. When you write:

return function send(o){ // notice the o in send
  return o;
}

      

The scope o

is local to the send function. But, if you write:

return function send(){
  return o;
}

      



The scope o is not local to send, but local to funcky.

So when you write function send(o){/*...*/}

, what actually happens is what o

becomes an argument and will need to be called like this: funcky()(10)

but what you want to do is funcky(10)()

.

EDIT:

For more information on variable scoping in JavaScript see this very detailed answer on SO .

+3


source


o

o

is the mistake where you make the mistake. It does not "inherit" o

from the original parent arguments. Putting inside this function declaration creates a new one o

inside the new scope of that function.

send

nothing is passed on the call and it returns its first argument for it to return undefined

.

Your code, annotated:



function funcky(o) {
    return function send(o){ // DECLARES NEW VARIABLE, happens to have same name
      return o; //returns the first argument passed to send
    }
  }

var x = funcky(3); //nothing is passed to the inner function send

console.log(x()); // undefined due to lack of arguments

      

A slightly clearer example of what is actually happening:

function funcky(o) {
   return function send(someArgument){
     return someArgument; //return o; here would find the correct o, the first arg of funcky
   }
}

      

+4


source


function funcky(o) {
    return function send(o){ // notice the o in send
      return o;
    }
}

      

The parameter to your inner function is o

shadowing the o

one originally passed to funcky

. So when you write var x = funcky(3);

x is just a function send

that waits for a parameter to return, nothing is captured in the closure.

(In other words, x has no reference to the original o

- 3 in your case, because by the name o, it calls the parameter that x itself is called with).

+2


source


Because of the volume.

The send function overwrites var o in the inner scope.

function funcky(o) {
// o here is whatever you passed in funcky
  return function send(o){
  // now o here is whatever you pass in send
  // since you didn't pass anything the result is undefined
    return o;
  }
}

      

Check out this other example

function funcky(o) {
  return function send(a){
    console.log(a);
    console.log(o); // this o is the parent o
    return o;
  }
}

var x = funcky(3);

console.log(x());

      

+2


source







All Articles