Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access my instance 'this' from revealing prototype?

I want to use the Revealing Prototype pattern, let's say I have a simple object

function Obj(name) {
    this.name = name;
}

Obj.prototype = (function() {
    var p1 = function() {
        return p2();
    };

    var p2 = function() {
        return this.name;
    };

    return {
        f1: p1,
        f2: p2
    };
}());

I construct with

var o = new Obj('Hello');

now o.f2() gives me Hello but o.f1() gives me undefined. I am able to get around this by passing the scope via call such as p2.call(this), however this becomes combersome with a lot of functions. Ideally I would want to be able to do a self = this type assignment so that I can just do self.name anywhere in the code.

How do I do this?

like image 678
happygilmore Avatar asked Nov 10 '22 06:11

happygilmore


1 Answers

Because the nature of JavaScript function invocation is what it is, and because the prototype code has to work for any of its "client" objects, it's hard to eliminate the explicit management of the context (this). One possible approach that may be preferable to using .call() or .apply() all over the place is to transform the functions such that the context is made an explicit parameter. You can do this with .call() and .bind():

Obj.prototype = (function() {
    var p1 = function() {
        return cp2(this);
    };

    var p2 = function() {
        return this.name;
    };

    var cp1 = p1.call.bind(p1);
    var cp2 = p2.call.bind(p2);

    return {
        f1: p1,
        f2: p2
    };
}());

With that, "cp1" and "cp2" are basically aliases that can be used instead of the explicit reference to .call(). The first argument is the value to be used as the context.

Note that in the prototype, you don't want to bind anything to this, since it's different for each object instance.

like image 144
Pointy Avatar answered Nov 14 '22 23:11

Pointy