1

Per this answer (https://stackoverflow.com/a/28281845/1477388) I understand I can create a javascript object with it's own properties and methods like so.

However, when attempting to assign a particular method via a callback, it doesn't work!

Why can't I simply pass the method instead of passing the entire object?

JS Fiddle: https://jsfiddle.net/Lson3qwx/1/

// base `Person` prototype
var Person = {
   name : '',
   age  : 22,
   type : 'human',
   msg: function(message) {
    alert(message);
   },
   greet: function() {
       //console.log('Hi, my name is ' + this.name + ' and I am a ' + this.type + '.' );
       this.msg('Hi, my name is ' + this.name + ' and I am a ' + this.type + '.');
   }
};

// create an instance of `Person`:
var skywalker = Object.create(Person);
skywalker.name = 'Anakin Skywalker';
//skywalker.greet(); // 'Hi, my name is Anakin Skywalker and I am a human.'

var callbackTest1 = function(callback) {
    callback.greet();
}

var callbackTest2 = function(callback) {
    callback();
}

callbackTest1(skywalker); // this works
callbackTest2(skywalker.greet); // this doesn't
user1477388
  • 20,790
  • 32
  • 144
  • 264
  • `Why can't I simply pass the method instead of passing the entire object?` because of how `this` works in JS. `callback()` in `callbackTest2` is equivalent to `skywalker.greet.call(null)`. – Thomas Aug 18 '17 at 20:36
  • 1
    The difference is the scope. In the second case, when you execute `greet`, `this` is not Skywalker. But you can do: `callbackTest2(skywalker.greet.bind(skywalker));` – blex Aug 18 '17 at 20:37
  • Incidentally, fighting the use of `new` is basically an anti-pattern, since newer core constructor functions and ES6 classes all require the use of `new`. – Alexander O'Mara Aug 18 '17 at 20:37
  • You can do : `callbackTest2(skywalker.greet());`. – DjaouadNM Aug 18 '17 at 20:37
  • @MrGeek No, in this case, `callbackTest2` is basically useless because you `greet` before even executing `callbackTest2`, and you're passing the result of `greet` (null) as a parameter. – blex Aug 18 '17 at 20:38
  • @MrGeek, this does something completely different – Thomas Aug 18 '17 at 20:38
  • @blex Wow, thanks that does work. It's a bit unclear what it is doing. I understand it is binding "skywalker" as the context. Is there a better way to write this? I am simply trying to pass a method property of an object as a callback. – user1477388 Aug 18 '17 at 20:40
  • 1
    I'm not really good at this, but here is a way I can think of: https://jsfiddle.net/f0L32prd/ – blex Aug 18 '17 at 20:45
  • @blex Awesome, that's so much cleaner. Well done! – user1477388 Aug 18 '17 at 20:47

0 Answers0