简体   繁体   中英

Understanding javascript call function

'use strict';

let worker = {
  someMethod() {
    return 4;
  },

  slow(x) {
    return x * this.somemethod();
  }
};

function wrapper(func) {
  return function(x) {
    let result = this.func(x);  // **
    return result;
  };
}

worker.slow = wrapper(worker.slow);
alert( worker.slow(2) );

When I run this code I get this error:

  TypeError:  this.func is not a function

If I replace the problematic line at ** with this:

let result = func.call(this, x);

I get the expected output. In this case it's 8.

I'm wondering why the way it's written is the wrong way to get "this" ie the object worker. In other words, how does the call function get the right object ie worker ?

The reason it's failing is that in the problematic line (highlighted with // **), you're effectively calling worker.func(x), which does not exist; You're not referring to the passed in variable at all.

If you add a function (func) to your worker, eg

let worker = {
  someMethod: function() {
    return 4;
  },

  slow: function(x) {
    return x * this.somemethod();
  },
  func: function (x) {
     return x * 10;
  }
};

And call as above eg

worker.slow = wrapper(worker.slow);
console.log( worker.slow(2) );

You'd find it works, though this is not what you really want!

In JavaScript, any function call obj.f(ArgumentList) will be desugared into f.call(obj, ArgumentList...) (see ecma-262 7.3.12 )

When wrapper(worker.slow) got a call, the function slow is passed into the wrapper and it produces another function which captured func argument. However, that function returned by wrapper is not called yet.

At a moment of the function call alert( worker.slow(2) ) func mean the argument that got captured in the closure and func.call(this, x) means it will call that function with the current caller, which is worker .

Therefore, `func.call(this,x)` will be `func.call(worker, x) `
which works because `func` exists in the closure.

while this means the reference to a current caller to the function(x){ ... }

Hence, `this.func(x)` will be `worker.func(x)` 
which `func` does not exist in `worker`.

if you try to insert console.log(func) and console.log(this) in that function, you will see the difference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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