简体   繁体   English

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

[英]understanding crockford's function that returns a function with a variable value

i was just watching Douglas Crockford videos and he gave the following exercise to do : 我只是看Douglas Crockford的视频,他做了以下练习:

write a function, that when passed a variable, returns a function 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 ?? 

notice the o in send. 注意发送中的o i have been programming javascript for a while now , but i still don't understand why i get undefined ?? 我已经编写了一段时间的JavaScript,但我仍然不明白为什么我得到未定义?

crockfords solution was as follows : crockfords解决方案如下:

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

  var x = funcky(3);

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

now how come this solution works and mine does't ? 现在为什么这个解决方案有效,我的呢? i don't see much of a difference in my solution and nothing is obviously wrong that i see. 我没有看到我的解决方案有太大的不同,我看到的任何事情都没有明显错误。 can anybody explain please ? 有人可以解释一下吗?

The o in the send(o){ is where you are making a mistake. osend(o){是你犯了一个错误。 It is not 'inheriting' the o from the original parent's arguments. 它不是从原始父母的论据中“继承” o Putting it inside that function declaration is creating a new o , inside a new scope of that function. 将它置于该函数声明中是在该函数的新范围内创建一个新的o

send isn't passed anything when called, and it returns its first argument so it returns undefined . 调用时send不会传递任何内容,并返回其第一个参数,因此返回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 occuring: 实际发生的事情的一个更清晰的例子:

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

This has to do with the scope of o . 这与o的范围有关。 When you write: 当你写:

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

The scope of o is local to the function send. o的范围是函数send的本地范围。 But, if you write: 但是,如果你写:

return function send(){
  return o;
}

The scope of o is not local to the function send, but is local to the scope of funcky. o的范围不是函数send的本地范围,而是funcky范围的本地范围。

So, when you write function send(o){/*...*/} what is really happening is that o becomes an argument, and would need to be called like this: funcky()(10) , but what you want to be able to do is funcky(10)() . 所以,当你编写function send(o){/*...*/} ,真正发生的是o成为一个参数,并且需要像这样调用: funcky()(10) ,但你想要什么能做的就是funcky(10)()

EDIT: 编辑:

For more information about variable scope in JavaScript, please see this very detailed answer on SO . 有关JavaScript中变量范围的更多信息,请参阅有关SO的详细答案

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

Your inner function's o parameter shadows the o originally passed to funcky . 你的内部函数的o参数会影响最初传递给funckyo So when you write var x = funcky(3); 所以当你写var x = funcky(3); , x is just a send function which expects a parameter to return, there's nothing captured in a closure. ,x只是一个send函数,它需要一个参数返回,在闭包中没有捕获任何东西。

(In other words, x doesn't have a reference to the original o - 3 in your case, because by the name o it calls the parameter that x itself is called with). (换句话说,x在你的情况下没有对原始o - 3的引用,因为通过名称o它调用x本身被调用的参数)。

Because of scope. 因为范围。

The function send overwrites the var o in its inner scope. 函数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;
  }
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM