理解crockford的函数,它返回一个带有变量值的函数

时间:2015-07-09 16:54:41

标签: javascript scope

我只是在观看Douglas Crockford的视频,他还做了以下练习:

  

编写一个函数,当传递一个变量时,返回一个函数   如果被调用,则返回变量的值。

所以我写了以下函数:

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 ?? 

注意发送中的o。我已经编写了一段时间的JavaScript,但我仍然不明白为什么我得到未定义?

crockfords解决方案如下:

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

  var x = funcky(3);

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

现在该解决方案如何运作,而我的解决方案是什么?我没有看到我的解决方案有太大的不同,我看到的任何事情都没有明显错误。有人可以解释一下吗?

4 个答案:

答案 0 :(得分:4)

o中的send(o){是您犯错误的地方。它不是继承'来自原始父级参数的o。将它置于该函数声明中是在该函数的新范围内创建一个新的o

send在调用时未传递任何内容,并返回其第一个参数,因此返回undefined

您的代码,注释:

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

实际发生的事情的一个更清晰的例子:

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

答案 1 :(得分:3)

这与o的范围有关。当你写:

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

o的范围是函数send的本地范围。但是,如果你写:

return function send(){
  return o;
}

o的范围不是函数send的本地范围,而是本地范围内的funcky。

所以,当你写function send(o){/*...*/}时,真正发生的是o成为一个参数,并且需要像这样调用:funcky()(10),但你想要的是什么要做的是funcky(10)()

编辑:

有关JavaScript中变量范围的详细信息,请参阅this very detailed answer on SO

答案 2 :(得分:2)

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

您的内部函数的o参数会隐藏最初传递给o的{​​{1}}。因此,当您编写funcky时,x只是一个var x = funcky(3);函数,它需要返回一个参数,在闭包中没有捕获任何内容。

(换句话说,在你的情况下,x没有对原始send - 3的引用,因为通过名称o它调用x本身被调用的参数。)

答案 3 :(得分:2)

由于范围。

函数send会覆盖其内部范围内的var o。

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;
  }
}

检查另一个例子

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());