Javascript:';受保护';范围界定

Javascript:';受保护';范围界定,javascript,scope,Javascript,Scope,如何在javascript中实现“受保护变量” var DIM = { makeOneDim: function(x) { var magic = Math.random(); return { dist: function() { return x * magic; } }; }, makeTwoDim: function(x,y) { var o = DIM.makeOneDim(x); o.dist

如何在javascript中实现“受保护变量”

var DIM = {
  makeOneDim: function(x) {
    var magic = Math.random();
    return {
      dist: function() {
        return x * magic;
      }
    };
  },
  makeTwoDim: function(x,y) {
    var o = DIM.makeOneDim(x);
    o.dist = function() {       
      magic *= Math.random();
      return Math.sqrt(x*x+y*y) * magic;
      // !! cant access 'private' variable magic !!
    }
    return o;
  }
};
var o = DIM.makeOneDim(123);
var oo = DIM.makeTwoDim(1,2);
console.log(o.dist() + oo.dist());
我知道在这个例子中可以生成一个“public getter”,但我仍然希望在MakeTowDim的范围内对magic变量进行变异,并将其隐藏在实例中


如果我能以某种方式阻止在每次创建实例时重新创建dist函数,那也很好。

有很多方法可以实现这一点,但最简单的方法是将函数保持在一起:

var DIM = {
  makeOneDim: function(x) {
    var magic = Math.random();
    var dist = function() {
      return x * magic;
    };

    var dist2 = function(y, y) {       
      magic *= Math.random();
      return Math.sqrt(x*x+y*y) * magic;
    };

    return {
      dist : dist,
      dist2 : dist2,
    };
  }
};

(而且,您真的想在每次调用时更改
magic
的值吗?

有很多方法可以实现这一点,但最简单的方法是将函数保持在一起:

var DIM = {
  makeOneDim: function(x) {
    var magic = Math.random();
    var dist = function() {
      return x * magic;
    };

    var dist2 = function(y, y) {       
      magic *= Math.random();
      return Math.sqrt(x*x+y*y) * magic;
    };

    return {
      dist : dist,
      dist2 : dist2,
    };
  }
};

(而且,您真的想在每次通话中更改
magic
的值吗?

这是否符合您的需要?它使用显示模块模式使
magic
私有化并返回函数。因此,无需从
makeTwoDim
调用
makeOneDim

var DIM = (function () {

  var magic = Math.random();

  function makeOneDim(x) {
    return {
      dist: function() {
        return x * magic;
      }
    };
  }

  function makeTwoDim(x, y) {
    return {
      dist: function() {
        magic *= Math.random();
        return Math.sqrt(x * x + y * y) * magic;
      }
    }
  }

  return {
    makeOneDim: makeOneDim,
    makeTwoDim: makeTwoDim
  }

});

var o = DIM().makeOneDim(123);
var oo = DIM().makeTwoDim(1,2);

这适合你的需要吗?它使用显示模块模式使
magic
私有化并返回函数。因此,无需从
makeTwoDim
调用
makeOneDim

var DIM = (function () {

  var magic = Math.random();

  function makeOneDim(x) {
    return {
      dist: function() {
        return x * magic;
      }
    };
  }

  function makeTwoDim(x, y) {
    return {
      dist: function() {
        magic *= Math.random();
        return Math.sqrt(x * x + y * y) * magic;
      }
    }
  }

  return {
    makeOneDim: makeOneDim,
    makeTwoDim: makeTwoDim
  }

});

var o = DIM().makeOneDim(123);
var oo = DIM().makeTwoDim(1,2);

您应该能够通过将
o.dist()除以
x来确定
makeTwoDim
magic
的值

var o = DIM.makeOneDim(x);    
var magic = o.dist() / x;
console.log(magic)

通过将
o.dist()
除以
x

var o = DIM.makeOneDim(x);    
var magic = o.dist() / x;
console.log(magic)

您需要使环境具有范围功能

jQuery方法:
您需要使环境具有范围功能

jQuery方法:
我知道我可能会收集腐烂的西红柿,但我想说,我不同意在JavaScript OOP范围内使用“受保护”或“私有”变量。JavaScript中没有内置的保护措施,开发人员注定会比其他人做得更好,就是这样:-D不要试图模仿Java,只是把它当作一个提高编程技能的机会。因此,这段代码在我看来非常完美:

AClass = function () {
  // `rdm` should never change
  this.rdm = Math.random();
};

我知道我可能会收集腐烂的西红柿,但我想说,我不同意在JavaScript OOP范围内使用“受保护”或“私有”变量。JavaScript中没有内置的保护措施,开发人员注定会比其他人做得更好,就是这样:-D不要试图模仿Java,只是把它当作一个提高编程技能的机会。因此,这段代码在我看来非常完美:

AClass = function () {
  // `rdm` should never change
  this.rdm = Math.random();
};

这将不起作用,因为
magic
仍然是第一个函数的本地函数。@Malvolio cool确实起作用。我希望在只需要oneDim对象的场景中避免膨胀。如果我给DIM/twoDim/任何与oneDim对象无关的东西添加更多功能,情况就更糟了。@Andy--
magic
makeOneDim
的本地用户(嗯,我应该更改名称)。对
dist
dist2
来说,它都是“关闭的”--这与它听起来的意思正好相反,它的意思是“可用的”--对,对不起,我没有注意到你做了什么。@iluvAS--这个“膨胀”是4字节,远远少于你能想到的任何其他解决方案。“程序员浪费大量时间考虑或担心其程序中非关键部分的速度,而在考虑调试和维护时,这些提高效率的尝试实际上会产生强烈的负面影响。我们应该忘记小效率,比如说97%的时间。”--Donald KnuthThis不起作用,因为
magic
仍然是第一个函数的本地函数。@Malvolio确实起作用了。我希望在只需要oneDim对象的场景中避免膨胀。如果我给DIM/twoDim/任何与oneDim对象无关的东西添加更多功能,情况就更糟了。@Andy--
magic
makeOneDim
的本地用户(嗯,我应该更改名称)。对
dist
dist2
来说,它都是“关闭的”--这与它听起来的意思正好相反,它的意思是“可用的”--对,对不起,我没有注意到你做了什么。@iluvAS--这个“膨胀”是4字节,远远少于你能想到的任何其他解决方案。“程序员浪费大量时间考虑或担心其程序中非关键部分的速度,而在考虑调试和维护时,这些提高效率的尝试实际上会产生强烈的负面影响。我们应该忘记小效率,比如说97%的时间。”--Donald Knuthyes!这非常有效,但我确实担心每次都必须重新创建DIM实例的性能,特别是如果我要在创建库时实现此逻辑,那么就本例和您的情况而言,它们不是类意义上的对象实例。您可以使用构造函数创建它们。我不会太担心性能,除非你注意到真正的下降。构造函数可能会有帮助。是的!这非常有效,但我确实担心每次都必须重新创建DIM实例的性能,特别是如果我要在创建库时实现此逻辑,那么就本例和您的情况而言,它们不是类意义上的对象实例。您可以使用构造函数创建它们。我不会太担心性能,除非你注意到真正的下降。构造函数可能会有所帮助。哇,很酷的解决方法!但这也会将魔法暴露于实例中,在这种情况下,我的示例是有缺陷的,但我相信您知道我的意思。@iluvAS“但这也会将魔法暴露于实例中”不确定您的意思?哇,很酷的解决方法!但这也会使实例具有魔力,在这种情况下,我的示例是有缺陷的,但我相信您知道我的意思。@iluvAS“但这也会使实例具有魔力”不确定您的意思?