GithubHelp home page GithubHelp logo

Comments (3)

trusktr avatar trusktr commented on May 29, 2024

Private methods also aren't private in the same way.

from mozart.

trusktr avatar trusktr commented on May 29, 2024

I got inspired and made my own implementation (first draft, it's messy, don't judge! 😆 ):

https://github.com/trusktr/lowclass/blob/8ee55a921af84e2682c93f76ea8c95b23b825083/src/index.js

Following is some code you can run against it to see how protected and private really are protected and private in the Java sense. Of course, if you really really try, you can probably still gain access, but it would require modifying source modules, which isn't convenient for end users importing stuff from libraries.

const Class = require('./src/index')

const Animal = Class('Animal', (p, _, __) => ({

    // anything outside the public/protected/private definitions is
    // automatically public.
    constructor: function(name) {
        this.blah = "blah"
        _(this).anything = 1234
        __(this).name = name
        console.log('Animal.constructor, PUBLIC instance', this)
        console.log('Animal.constructor, PROTECTED instance', _(this), /*from Dog*/_(this).sound)
        console.log('Animal.constructor, PRIVATE instance', __(this))
    },

    public: {
        talk: function talk() {
            _(this).lorem = 'lorem'
            __(this).saySecret()
            _(this).animalMethod()
            console.log('Animal.talk, PUBLIC instance', this)
            console.log('Animal.talk, PROTECTED instance', _(this))
            console.log('Animal.talk, PRIVATE instance', __(this))
        },
    },

    protected: {
        sound: "aruuugah",
        animalMethod: function() {
            this.dude = "dude"
            console.log('Animal._animalMethod, PUBLIC instance', _(this))
            console.log('Animal._animalMethod, PROTECTED instance', this)
            console.log('Animal._animalMethod, PRIVATE instance', __(this))
        },
    },

    private: {
        foo: "foo",
        saySecret: function() {
            console.log('raaaaaawr, I am ' + this.name)
            console.log('Animal.__saySecret, PUBLIC instance', __(this))
            console.log('Animal.__saySecret, PROTECTED instance', _(this))
            console.log('Animal.__saySecret, PRIVATE instance', this)
        },
    },
}))

const Dog = Animal.subclass(function Dog(pub, prot, priv) {

    pub.constructor = function(name) {
        Animal.call(this, name+'!')
        priv(this).trained = true
        prot(this).foo()
        console.log('Dog.constructor, PUBLIC instance', this)
        console.log('Dog.constructor, PROTECTED instance', prot(this))
        console.log('Dog.constructor, PRIVATE instance', priv(this))
    }

    pub.talk = function() {
        Animal.prototype.talk.call(this)
        console.log('Dog.talk, PUBLIC instance', this)
        console.log('Dog.talk, PROTECTED instance', prot(this))
        console.log('Dog.talk, PRIVATE instance', priv(this))
    }

    prot.sound = "Woof!"
    prot.foo = function() {
        if (prot(this).trained) console.log(priv(this).lorem + "!")
        priv(this).downwardDog()
        console.log('Dog._foo, PUBLIC instance', prot(this))
        console.log('Dog._foo, PROTECTED instance', this)
        console.log('Dog._foo, PRIVATE instance', priv(this))
    }

    priv.lorem = "lorem"

    return {
        private: {
            downwardDog: function() {
                console.log('Dog.__downwardDog, PUBLIC instance', priv(this))
                console.log('Dog.__downwardDog, PROTECTED instance', prot(this))
                console.log('Dog.__downwardDog, PRIVATE instance', this)
            }
        }
    }
})

const animal = new Dog('Ranchuu')
animal.talk()

try {
    const UnrelatedClass = Class(function UnrelatedClass(p, _, __) {
        __.ipsum = 'ipsum'
        p.someMethod = function() {
            let d = new Dog('Doggie')
            console.log('Access PROTECTED stuff:', _(d).sound)
        }
    })

    let u = new UnrelatedClass
    u.someMethod()
}
catch (e) {
    console.log('Success, there was an error on invalid PROTECTED access')
}

try {
    const UnrelatedClass = Class(function UnrelatedClass(p, _, __) {
        __.ipsum = 'ipsum'
        p.someMethod = function() {
            let d = new Dog('Doggie')
            console.log('Access PRIVATE stuff:', __(d).lorem)
        }
    })

    let u = new UnrelatedClass
    u.someMethod()
}
catch (e) {
    console.log('Success, there was an error on invalid PRIVATE access')
}

try {
    let Dog

    const Animal = Class('Animal', (p, _, __) => ({
        public: {
            foo: function talk() {
                const dog = new Dog
                console.log('Access Dog\'s PROTECTED from Animal:', _(dog).sound)
            },
        },
    }))

    Dog = Animal.subclass(function Dog(_public, _protected, _private) {
        _protected.sound = "Woof!"
    })

    const animal = new Animal('Ranchuu')
    animal.foo()

    console.log('Success, we were able to access Dog\'s PROTECTED member.')
}
catch (e) {
    console.log('Uh oh, there shouldn\'t have been problem accessing PROTECTED stuff from Dog')
}

try {
    let Dog
    let itWorks = true

    const Animal = Class('Animal', (p, _, __) => ({
        public: {
            foo: function talk() {
                const dog = new Dog
                console.log('Access Dog\'s PRIVATE from Animal:', itWorks = !__(dog).sound)
                if (!itWorks) return

                __(dog).bar = 'NOT BAR'
                dog.foo()
                if (!itWorks) return

                itWorks = __(this).bar == 'BAR'
            },
        },

        private: {
            bar: 'BAR',
        },
    }))

    Dog = Animal.subclass(function Dog(_public, _protected, _private) {
        _protected.sound = "Woof!"
        _public.foo = function() {
            itWorks = !__(this).bar
        }
    })

    const animal = new Animal('Ranchuu')
    animal.foo()


    if (itWorks) console.log('Success (no error), we were not able to access Dog\'s PRIVATE member, although it created a new useless object.')
    else console.log('Uh oh, there should have been a problem accessing PRIVATE stuff from Dog')
}
catch (e) {
    console.log('Success (actual error), we were not able to access Dog\'s PRIVATE member.')
}

from mozart.

trusktr avatar trusktr commented on May 29, 2024

Things to notice in the example:

  • a class instance can't access protected or private stuff of an instance of an unrelated class.
  • A related class (for example a parent class) can access protected members of a related instance. I'm talking about separate instances accessing across each other (like Java).
  • The rest works like yours (an instance can access super protected stuff, but not super private stuff, and a super method of a child instance method call can only access private stuff of the class the method is defined in). Basically, one private object per class (no prototype chain) and one protected prototype chain that is parallel to the public chain.
  • I don't have a super helper like yours yet.
  • No accessor shortcut like yours (not planning on it).

I've also been thinking of other way that would make it cleaner. Maybe it is possible to implement without "key functions" by binding methods to prototype during construction. Another possibility might be to use Proxies. We'll save that for some more fun later...

from mozart.

Related Issues (7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.