JavaScript private methods

前端 未结 30 1862
-上瘾入骨i
-上瘾入骨i 2020-11-22 08:16

To make a JavaScript class with a public method I\'d do something like:

function Restaurant() {}

Restaurant.prototype.buy_food = function(){
   // something         


        
30条回答
  •  余生分开走
    2020-11-22 08:42

    Take any of the solutions that follow Crockford's private or priviledged pattern. For example:

    function Foo(x) {
        var y = 5;
        var bar = function() {
            return y * x;
        };
    
        this.public = function(z) {
            return bar() + x * z;
        };
    }
    

    In any case where the attacker has no "execute" right on the JS context he has no way of accessing any "public" or "private" fields or methods. In case the attacker does have that access he can execute this one-liner:

    eval("Foo = " + Foo.toString().replace(
        /{/, "{ this.eval = function(code) { return eval(code); }; "
    ));
    

    Note that the above code is generic to all constructor-type-privacy. It will fail with some of the solutions here but it should be clear that pretty much all of the closure based solutions can be broken like this with different replace() parameters.

    After this is executed any object created with new Foo() is going to have an eval method which can be called to return or change values or methods defined in the constructor's closure, e.g.:

    f = new Foo(99);
    f.eval("x");
    f.eval("y");
    f.eval("x = 8");
    

    The only problem I can see with this that it won't work for cases where there is only one instance and it's created on load. But then there is no reason to actually define a prototype and in that case the attacker can simply recreate the object instead of the constructor as long as he has a way of passing the same parameters (e.g. they are constant or calculated from available values).

    In my opinion, this pretty much makes Crockford's solution useless. Since the "privacy" is easily broken the downsides of his solution (reduced readability & maintainability, decreased performance, increased memory) makes the "no privacy" prototype based method the better choice.

    I do usually use leading underscores to mark __private and _protected methods and fields (Perl style), but the idea of having privacy in JavaScript just shows how it's a misunderstood language.

    Therefore I disagree with Crockford except for his first sentence.

    So how do you get real privacy in JS? Put everything that is required to be private on the server side and use JS to do AJAX calls.

提交回复
热议问题