undefined reference to object method in it's property on jQuery plugin

204 Views Asked by At

I have problem in line #27 (fiddle: https://jsfiddle.net/hh82p4fj/1/)

Why my property points to undefined while it's in the same closure?

"use strict";

function callself(instance, callback) { // saves 'this' state for reuse inside another function
    return function () {
        var argumentsList = [this], i;

        for (i = 0; i < arguments.length; i = i + 1) {
            argumentsList.push(arguments[i]);
        }

        return callback.apply(instance, argumentsList);
    };
}

var Namespace = function () {
    var settings = { handler: this.method };

    this.initialize = function () {
        $.fn.myPlugin = callself(this, function (that, userInput) {
            /* this = Namespace
               that = jQuery element
               userInput = provided in line 30 as parameter
            */
            console.log(this);
            console.log(that);
            console.log(userInput);
            console.log(settings.handler); // why why it's undefined?
        });

        $('body').myPlugin('someData');
    };

    this.method = function () { console.info('method'); }; // this method should be returned as reference in line 27, but it can not reah 'this` - don't know why
};
new Namespace().initialize();

callself is needed there, to preserve both jQuery this context ando ryginal object closure.

2

There are 2 best solutions below

0
On BEST ANSWER
var settings = { handler: this.method };

You assigned to settings.handler not a reference to this.method
but value of this.method (which is undefined at execution moment)

this.method must be an object to get referenced.


this.method = {}; //empty object
var settings = { handler: this.method };

this.method =>ref {}
settings.handler =>ref {}


this.method = {}; //empty object
var settings = { handler: this.method };
this.method = funtion(){}`// reference will be replaced

this.method =>ref funtion(){}
settings.handler =>ref {}


this.method = {}; //empty object
var settings = { handler: this.method };
this.method.use = function(){}

this.method =>ref {use: function(){}}
settings.handler =>ref {use: function(){}}


function Namespace(){
  
    var settings = {};

    this.initialize = function(){
        document.write(settings.handler())
    };

    settings.handler = function(){return 'Handled!'};
}
new Namespace().initialize()

1
On

The problem is the order of initialization.

You are using this.method at the be genning of the script when this.method = function(){} is not yet executed so the value of this.method is undefined when the setting object is created.

var Namespace = function () {
    //this should be set before `this.method` is referred
    this.method = function () {
        console.info('method');
    };

    var settings = {
        handler: this.method
    };

    this.initialize = function () {
        $.fn.myPlugin = callself(this, function (that, userInput) {
            /* this = Namespace
               that = jQuery element
               userInput = provided in line 30 as parameter
            */
            console.log(this);
            console.log(that);
            console.log(userInput);
            console.log(settings.handler); // why why it's undefined?
        });

        $('body').myPlugin('someData');
    };

};