Javascript 理解crockford';s函数,该函数返回具有变量值的函数

Javascript 理解crockford';s函数,该函数返回具有变量值的函数,javascript,scope,Javascript,Scope,我正在看道格拉斯·克罗克福德的视频,他做了以下练习: 写一个函数,当传递一个变量时,返回一个 如果调用,则返回变量的值 因此,我编写了以下函数: 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 ?? 注意send

我正在看道格拉斯·克罗克福德的视频,他做了以下练习:

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

因此,我编写了以下函数:

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 ?? 
注意send中的
o
。我已经编写javascript有一段时间了,但我仍然不明白为什么我没有定义

crockfords的解决方案如下:

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

  var x = funcky(3);

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

为什么这个解决方案有效而我的却不行?我看不出我的解决方案有多大的不同,我认为没有什么明显的错误。谁能解释一下吗

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

return function send(o){ // notice the o in send
  return o;
}
return function send(){
  return o;
}
o
的范围是函数send的本地范围。但是,如果你写:

return function send(o){ // notice the o in send
  return o;
}
return function send(){
  return o;
}
o的范围不是函数send的本地范围,而是funcky的本地范围

因此,当您编写
函数send(o){/*…*/}
时,实际发生的情况是
o
变成了一个参数,需要这样调用:
funcky()(10)
,但您希望能够做的是
funcky(10)(

编辑:


有关JavaScript中变量作用域的更多信息,请参阅
send(o)中的
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
   }
}
内部函数的
o
参数会对最初传递给
funcky
o
进行阴影处理。因此,当您编写
var x=funcky(3);
时,x只是一个
send
函数,期望参数返回,而闭包中没有捕获任何内容

(换句话说,在您的例子中,x没有对原始的
o
-3的引用,因为它通过名称o调用x本身被调用的参数)。

因为范围

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

Crockford正在返回一个不带参数的函数。它从外部函数获取它的参数。你的函数需要你提供的参数。所以基本上javascript有函数作用域,但我猜没有块作用域!