使用特权Getter / Setter函数的JavaScript原型函数?

时间:2013-12-16 21:00:33

标签: javascript constructor prototype getter-setter

由三部分组成的问题:

  1. 添加第二层抽象,并使用原型getter / setter函数调用特权构造函数getter / setter函数的任何值?请参阅下面的ns.Wheel.prototype.getWeight2()ns.Wheel.prototype.setWeight2()

  2. swiss.getWeight()的调用会调用构造函数中的this.getWeight()方法。有什么方法可以在原型链上移动一级来调用ns.Wheel.prototype.getWeight()

  3. “隐藏”构造函数getter / setter后面的“隐藏”原型getter / setter函数的任何值?例如,ns.Wheel.prototype.getWeight()在构造函数中隐藏在this.getWeight()方法后面。

  4. 还要注意原型getter / setter如何为克添加单位;即“g”单位。例如,this.getWeight返回1000,而ns.Wheel.prototype.getWeight返回1000g。

    在这个例子中使用了瑞士奶酪的轮子。

    (function(ns) {
        ns.Wheel = function() {
            var _weight = 1000; // weight of cheese wheel. Private variable.
            this.getWeight = function() { return _weight } // privileged weight getter
            this.setWeight = function(weight) { return _weight = weight } // privileged weight setter
        }
        ns.Wheel.prototype.getWeight = function() { return this.getWeight()+'g' }
        ns.Wheel.prototype.setWeight = function(weight) { return this.setWeight(weight)+'g' }
        ns.Wheel.prototype.getWeight2 = function() { return this.getWeight()+'g' }
        ns.Wheel.prototype.setWeight2 = function(weight) { return this.setWeight(weight)+'g' }
    })(window.cheese = window.cheese || {});  // immediate function namespacing technique
    
    var swiss = new cheese.Wheel();
    console.log(swiss.getWeight()); //-> 1000. Invokes constructor method
    console.log(swiss.setWeight(2000)); //-> 2000. Invokes constructor method
    console.log(swiss._weight); //-> undefined. Private variable!!!
    console.log(swiss.getWeight2()); //-> 2000g. Invokes prototype method.
    console.log(swiss.setWeight2(9000)); //->9000g. Invokes prototype method.
    

2 个答案:

答案 0 :(得分:4)

  1.   

    添加第二层抽象,并使用原型getter / setter函数来调用特权构造函数getter / setter函数的任何值?

    总的来说,我会说不。在可能的情况下在原型上存在方法会更加节省内存,因为在实例构造期间设置的方法将存在于每个实例上,而原型方法只需要定义一次。

  2.   

    任何方法都可以在原型链上移动一个级别来调用ns.Wheel.prototype.getWeight()

    如果您希望某些方法对构造函数内部定义的变量进行“私有”访问,则还必须在构造函数内定义这些函数。功能范围在声明时设置。因此,在构造函数之外定义的函数(例如,原型方法)无法访问构造函数范围变量。

    因为JavaScript函数是第一类对象,所以可以使用callapplyns.Wheel.prototype.setWeight.call(this, 1000)调用原型方法(其中第一个参数设置this值被调用的函数,以及其他参数是实际的函数参数。)

  3.   

    “隐藏”构造函数getter / setter后面的“隐藏”原型getter / setter函数的任何值?

    在您的情况下,永远不会使用ns.Wheel.prototype.getWeight(及其相应的setter)。当getWeight2调用this.getWeight()时,它会解析为实例级函数,并且无需查找原型方法的原型链。

    我能看到的唯一值可能是,如果你有条件地使用实例方法隐藏了一些原型方法,而在其他情况下让原型方法显示出来。但是,如果您希望该原型方法可以访问构造函数范围变量,那么您运气不错,如第2点所述。例如:

    function Egg(color) {
        if(color == "invisible") {
            this.examine = function() { return "You can't see the egg at all! }
        } 
    }
    
    Egg.prototype.examine = function() { return "The egg is painted " + color; }
    

    这不是一个很好的例子(对于像数字这样的简单值而不是函数,它效果更好),但它是我能想到的原型阴影的唯一“有用”示例。

  4. 我强烈支持上面的第二条评论,该评论建议不要使用私有变量。如我的第一点所述,它们浪费内存,要求在每个实例上定义使用它们的方法。通过尝试模拟私有变量,您浪费了原型继承的力量。相反(如评论中所述),将所有变量公开,并使用前导下划线指定“私有”变量。

答案 1 :(得分:1)

  

添加第二层抽象,并使用原型getter / setter函数调用特权构造函数的任何值   getter / setter函数?参见ns.Wheel.prototype.getWeight2()和   ns.Wheel.prototype.setWeight2()如下。

为什么不呢?好吧,请记住,调用函数很昂贵,所以如果只是在最后添加'g',你可以考虑手动执行它,如果你想获得一些微秒。

  

对swiss.getWeight()的调用将在构造函数中调用this.getWeight()方法。任何方式可以在原型链上移动一级   而是调用ns.Wheel.prototype.getWeight()?

是的,你可以:

  • 使用不同的名称
  • 使用cheese.Wheel.prototype.getWeight.call(swiss)
  

“隐藏”原型getter / setter函数“后面”的任何值   构造函数getter / setters?例如,ns.Wheel.prototype.getWeight()   在构造函数中的this.getWeight()方法后面“隐藏”。

这取决于具体情况。在你的情况下,我会使用不同的名称来避免“隐藏”。