0

I have an array of DataTable objects:

var scheme_tables = {
    length: 3,
    remittance-penalty-scheme: DataTable.Api._Api[0],
    reporting-penalty-scheme: DataTable.Api._Api[0],
    service-fee-scheme: DataTable.Api._Api[0],
    __proto__: Array[0]
}

I'm performing a callback to every ajax reload to each of these tables:

for(key in scheme_tables) {             
    scheme_tables[key].ajax.reload(reloader)
                                   ^^^^^^^^
}

And inside that reloader function, I have a this keyword:

var reloader = function() {
    console.log(this)
                ^^^^
}

Would the this keyword in the reloader() function refer to the .ajax property or the scheme_tables[key] object? Because when I perform console.log(this), I receive a Window object-- should it be referring to the DataTable instance instead?

Gideon
  • 1,339
  • 2
  • 18
  • 52
  • 4
    Your own test answers your question: `this` will be `window`. – dfsq Jul 01 '15 at 06:51
  • 1
    @gillesc no, that's irrelevant. What matters is how the function is invoked, not what object "owns" the function. – Alnitak Jul 01 '15 at 06:53
  • `this` is basically just an extra argument in JS, at least in the context of callbacks, you can set it to whatever you want – dandavis Jul 01 '15 at 06:53
  • @dfsq Thats why I want to know the reason behind... because I'm expecting it to be attached to the `DataTable` instance and hence when I use `this` it should represent the `object` where it has been attached. – Gideon Jul 01 '15 at 06:53
  • @Gideon in which case you need to use `.call(ctx, ...)` to invoke the callback within the `.reload` function, passing the required `this` value to `reloader`. – Alnitak Jul 01 '15 at 06:54
  • Then you should have asked question "why" and not "what will this be". And the answer to "why"-question is because in data tables they invoke callback as `callback( api.ajax.json() );` in which case context will be global object. So you expect `this` to be whatever, but developers decided to call callback in global context. If you really need it you can bind you callback to proper instance object. – dfsq Jul 01 '15 at 06:56
  • 1
    For the various ways that `this` is controlled in Javascript, see this answer: [What is a best practice for ensuring “this” context in Javascript?](http://stackoverflow.com/questions/16226751/what-is-a-best-practice-for-ensuring-this-context-in-javascript/16227099#16227099). – jfriend00 Jul 01 '15 at 07:05

2 Answers2

1

You should use .bind to create a reference to the reloader function that's bound to the required context:

for (key in scheme_tables) {
    var t = scheme_tables[key];                    
    t.ajax.reload(reloader.bind(t));
}

There's no need for the hasOwnProperty test - if anyone was messing with your Object.prototype then jQuery would be failing. The jQuery devs have made a very deliberate decision not to use hasOwnProperty in jQuery's iteration functions.

Alnitak
  • 313,276
  • 69
  • 379
  • 466
  • Is there a big difference/advantage between using ``reloader.bind(t)`` and just passing the object as argument ``reloader(object)`` and using the ``object`` variable inside the function? – tiblu Jul 01 '15 at 07:18
  • 2
    @gideon you can't just do `.reload(reloader(object))` because that will invoke `reloader` immediately with the supplied parameter instead of passing it as a callback. – Alnitak Jul 01 '15 at 08:14
0

In javascrpt keyword this inside a function is bound to whatever is left of the dot at the time of invocation. In your code reload internally invokes reloader function. And since it calls it without dont notation, this would be attached to window.

It doesnt matter where and how function is defined, this word always is defined at execution.

Or you can manaually specify what this would refer to using .bind

I would urge you to lookup udacity object oriented javascript course.

Muhammad Umer
  • 14,722
  • 14
  • 69
  • 139
  • 1
    you can't be _sure_ that `this === window` without looking at the actual invocation. If it uses `.call` or `.apply` then it could be set to anything. – Alnitak Jul 01 '15 at 06:59