Accessing "private" members of an anonymous function out of scope

Basically what I am trying to do is to provide "private" function / variable access to the anonymous function. I need a few opinions on two ways to achieve this and possible alternatives to those approaches. Fiddle

Observe the following snippet.

function Something()
{
    /*private*/ var _someVariable = 1;

    /*private*/ function _someFunction() {
        alert('_someFunction');
    }

    /*public*/this.SomeDelegate1 = function(codeblock) {
        var members = $.extend({ 
            _someVariable : _someVariable,
            _someFunction:_someFunction 
        }, this);           
        codeblock.apply(members);
    }

    /*public*/this.SomeDelegate2 = function(codeblock) {
        var caller = eval('(' + codeblock + ')');
        caller.apply(this);
    }           

}

      

In SomeDelegate1, I convert my private members to instance members and pass them as the context for the anonymous function as shown below.

var someInstance = new Something();
someInstance.SomeDelegate1(
    function() {
        this._someFunction();
        alert(this._someVariable);
    }
);

      

I love the fact that you can specify which members you would like to open, but it can potentially get pretty awkward, for example. when you need to update the "private" variables eg.

I can obviously write all members as instance members, but I would prefer that they remain "private", allowing access only within the scope of the callback function.

In SomeDelegate2, I use eval (yes, I know all the evil and witchcraft associated with this).

var someInstance = new Something();
someInstance.SomeDelegate2(
    function() {
        _someFunction();
        alert(_someVariable);
    }
);

      

Since I was injecting code into the function, the extended-reach "confidential" members are automatically available, so I don't need to make any copies of the members, etc., and don't have to do a lot of work. >

Are there fundamental problems with this approach?

Do you have any better alternatives / approaches to achieve this?

+3


source to share


1 answer


As I said in my comment, I would make everything public and prefix "private" with underscore property names. This is how I would restructure your code:



function defclass(prototype) {
    var constructor = prototype.constructor;
    constructor.prototype = prototype;
    return constructor;
}

var Something = defclass({
    constructor: function () {
        this._someVariable = 1;
    },
    _someFunction: function () {
        alert("someFunction");
    },
    someDelegate1: function (f) {
        f.apply(this);
    },
    someDelegate2: function (f) {
        f.call(this, this._someVariable, this._someFunction);
    }
});

var someInstance = new Something;

someInstance.someDelegate1(function () {
    this._someFunction();
    alert(this._someVariable);
});

someInstance.someDelegate2(function (someVariable, someFunction) {
    someFunction();
    alert(someVariable);
});
      

Run codeHide result


However, this is just my opinion. I see no point in having private variables. Even if someone messes up your personal variables, that's their problem, not yours. This will break their code, not yours.

+1


source







All Articles