How are parameters handled when passing functions in Javascript? [duplicate]

こ雲淡風輕ζ 提交于 2019-12-23 09:17:45

问题


In http://eloquentjavascript.net/1st_edition/chapter6.html, there is the following example:

function negate(func) {
  return function(x) {
    return !func(x);
  };
}
var isNotNaN = negate(isNaN);
alert(isNotNaN(NaN));

Knowing only basic Javascript and imperative programming, I am stumped by this programming style. Can someone help me to understand what happens during runtime.

I stepped through the code and inspected variables and found that the value of x is NaN. How does it know that the argument to isNaN should be passed as argument x of the anonymous function? In the first place, why does the actual parameter NaN of isNotNaN become the argument to isNaN (ie while isNaN expects an argument, why does it take it from the argument of isNotNaN)?


回答1:


Best way to understand this might be with seeing what these things actually equal. Notice how func becomes the passed isNaN function.

function negate(func) {
  return function(x) {
    return !func(x);
  };
}
var isNotNaN = negate(isNaN);
/*

isNotNaN = function(x){
   return !isNaN(x)
}

*/

alert(isNotNaN(NaN));



回答2:


Notice that negate both accepts a function as an argument and returns a function. The returned function will call the argument function, negating the return value. Thus, isNotNaN is a function. When it is called, it will call the function originally passed into negate, in this case isNaN. Whatever you call isNotNaN with will be passed to isNaN.

In essence, you're configuring a function with another function. This might be easier to see with a simpler (no argument function) example:

function addX(x) {
    return function(y) {
        return x+y;
    };
}

var add2 = addX(2);
console.log(add2(2)); // 4

var add3 = addX(3);
console.log(add3(7)); // 10

Now, take this one step further and imagine you passed a function into addX instead of a value.

By the way, this is called currying.




回答3:


It is because you set this:

   var isNotNaN = negate(isNaN);

And when calling isNotNaN(x)so it is like you call negate(isNaN)(x). You can also use a named function instead of the anonymous here so we say:

    function negate(func) {
      return xValue.call(this, x); //to be in the context of the xValue function
      };
   }
    var isNotNaN = negate(isNaN);
    alert(isNotNaN(NaN));

    function xValue(x) {
       return !func(x);
    }

    But then you have to take care about the context.


来源:https://stackoverflow.com/questions/32669993/how-are-parameters-handled-when-passing-functions-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!