Javascript:实现100%防篡改私有变量的方法?

时间:2011-11-30 17:46:53

标签: javascript

我正在阅读Crockford的教程http://javascript.crockford.com/private.html。 私有变量由构造函数内部的函数实现,可以将私有变量关联到闭包。

通常javascript库是开放的,所以任何人都可以通过修改构造函数通过实例/对象的内部函数来查看和修改私有变量。像这样: c1.radius = function(){return 500;};

更精确地说:在真正的OOPS中,没有人可以通过对象修改私有变量,但我们可以这样做。

任何人都可以建议我像JAVA或C那样完全防篡改吗?

function Circle(radius) {

this.radius = function(){ return radius;}

}

Circle.prototype = {
   constructor: Circle,
   area: function(){
       return (Math.PI)* (Math.pow(this.radius(),2));
   }
};

c1 = new Circle(5);
console.log(c1.radius());
console.log(c1.area());
c1.radius = function (){return 500;};

3 个答案:

答案 0 :(得分:2)

这个怎么样?

function oTest(){
  var a; // "private"
  this.b; // "public"

  this.get_a = function(){
    return a
  )
}

var aTest = new oTest();
aTest.private_get = function(){
  return a
} 

aTest.private_get() // ReferenceError: a is not defined
aTest.get_a() // works

我不确定我是否完全理解您的问题,但只有原始的一套方法才能使用。

答案 1 :(得分:1)

第一关,不要太担心防篡改。如果有人真的想要,他们将能够访问他们想要的东西。

2,除非您使用ECMAScript 5(IE9 +,Safari 5 +,Chrome 7 +,FF 4+),否则您无法真正做到这一点。如果您使用的是ES5浏览器,则可以使用Object.defineProperty方法或使用Object.create执行所需操作:

function Circle(radius) {
    Object.defineProperty(this, 'radius', {
        value: radius
    });
}

注意:使用Object.createObject.defineProperty时,属性默认为不可写,不可配置(类型无法更改,属性无法删除),且不可枚举(不会显示在for(var x in obj)构造中)。

答案 2 :(得分:1)

您可能需要查看traits.js。在以下示例中,半径和区域是不可变的或防篡改的。

function TCircle(radius) {
    return Trait.create(
        Object.prototype,
        Trait({
            radius: radius,
            area: function() {
                return (Math.PI) * (Math.pow(this.radius, 2));
            }
        }));
}

var circle = TCircle(5);
console.log(circle.area()); // 78.53981633974483
circle.radius = null;
console.log(circle.area()); // 78.53981633974483
circle.radius = 99;
console.log(circle.area()); // 78.53981633974483

如果你想要一个可变对象,那么你可以使用Object.create而不是上面的Trait.create