Private variables in inherited prototypes

后端 未结 4 1128
温柔的废话
温柔的废话 2020-12-05 00:54

I think I have misunderstood how Javascript prototypal inheritance works. Specifically, the prototypes internal variables seem to be shared between multiple different sub-ob

4条回答
  •  庸人自扰
    2020-12-05 01:33

    I just found other tricky solution, without exporting any methods/variables to public objects.

    function A(inherit) {
        var privates = { //setup private vars, they could be also changed, added in method or children
            a: 1,
            b: 2,
            c: 3
        };
        //setup public methods which uses privates
        this.aPlus = bindPlus("aPlus", this, privates); //pass method name as string!
        this.aGet = bindPlus("aGet", this, privates);
        if (inherit) {
            return privates;
        }
    }
    A.prototype.aPlus = function () {
        var args = getArgs(arguments),
            //self is "this" here 
            self = args.shift(),
            privates = args.shift(),
            //function real arguments
            n = args.shift();
        return privates.a += n;
    };
    
    A.prototype.aGet = function (n) {
        var args = getArgs(arguments),
            self = args.shift(),
            privates = args.shift();
        console.log(this, self, privates);
        return privates.a;
    };
    
    //utilites
    function getArgs(arg) {
        return Array.prototype.slice.call(arg);
    }
    
    function bindPlus(funct, self, privates) {
        return function () {
            return Object.getPrototypeOf(self)[funct].bind(this, self, privates).apply(null, arguments);
        };
    }
    
    //inherited 
    function B(inherit) {
        var privates = Object.getPrototypeOf(this).constructor.call(this, true);
        privates.d = 4;
        this.dGet = bindPlus("dGet", this, privates);
        if (inherit) {
            return privates;
        }
    }
    
    B.prototype = Object.create(A.prototype);
    B.constructor = B;
    
    B.prototype.aGet = function () {
        var args = getArgs(arguments),
            self = args.shift(),
            privates = args.shift();
        console.warn("B.aGet", this, privates);
        return privates.a;
    };
    
    B.prototype.dGet = function () {
        var args = getArgs(arguments),
            self = args.shift(),
            privates = args.shift();
        console.warn("B.dGet", this, privates);
        return privates.d;
    };
    
    
    // tests
    var b = new B();
    var a = new A();
    
    //should be 223
    console.log("223 ?",b.aPlus(222));
    
    //should be 42
    console.log("41",a.aPlus(222));
    

    More test and samples here: http://jsfiddle.net/oceog/TJH9Q/

提交回复
热议问题