问题描述:

function foo(obj, method, ...args) {

if (!(method in obj)) return null;

try {

alert(!!obj); //shows true

return obj[method].apply(obj, args);

}

catch (e) {

alert(e);

}

}

When I call foo with a defined object, a valid method of it and some args, it shows:

TypeError: this is undefined.

What does this mean?

I thought this would be important here because I'm using apply whose 1st param will be used as this inside the method invoked. But here obj is valid and it doesn't even invoke the required method. An error is caught even before.

(...args means any extra arguments passed to foo after obj and method will be pushed into an array args which can be used by foo)

EDIT: ...args is valid. It's ES6.

EDIT: My code seems perfectly fine. I'm trying to check and see if the called function has something wrong. Sorry if that is the case.

EDIT: I'm sorry, the problem turned out to be with the method that was being invoked. I had said otherwise, but I was confused.

There was another callback in it.

array.forEach(function (a) { // do something with 'this'});

this was obviously being undefined since it didn't refer to the object.

网友答案:

demo

I changed your function to this. First we narrow down the parameters, to make sure they are of the correct types. We need an obj and a method. Furthermore, obj[method] better be a function, because we're trying to call it.

function foo(obj, method) {
  if (typeof obj === 'undefined' 
   || typeof method !== 'string' 
   || typeof obj[method] !== 'function') {
          return null;
  }

I'm not sure how ES6 works, and have no way to test it, but this should continue to work. If you can get it to work without, it's an easy change (removing this line, and adding a parameter).

  var args = Array.prototype.slice.call(arguments, 2);
  return obj[method].apply(obj, args);e);
}

We can test it by giving it a Person.

function Person(){
    this.say_name = function(first, last){
        alert('My name is ' + first + ' ' + last);
    };
}

var Me = new Person();
foo(Me, "say_name", "John", "Doe"); // shows "My name is John Doe"

Just ask if you need further explanation.

相关阅读:
Top