简体   繁体   English

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

[英]JavaScript Prototype Functions Using Privileged Getter/Setter Functions?

Three-part question: 三部分问题:

  1. Any value to adding a second layer of abstraction, and using a prototype getter/setter function to invoke privileged constructor getter/setter functions? 添加第二个抽象层并使用原型getter / setter函数调用特权构造函数getter / setter函数有什么价值? See ns.Wheel.prototype.getWeight2() and ns.Wheel.prototype.setWeight2() below. 请参见ns.Wheel.prototype.getWeight2()ns.Wheel.prototype.setWeight2()

  2. The call to swiss.getWeight() invokes the this.getWeight() method in the constructor. 调用swiss.getWeight()调用构造函数中的swiss.getWeight() this.getWeight()方法。 Any way to move one level up the prototype chain to instead invoke ns.Wheel.prototype.getWeight() ? 以任何方式将原型链向上移动一级来调用ns.Wheel.prototype.getWeight()吗?

  3. Any value to "hiding" the prototype getter/setter functions "behind" the constructor getter/setters? 对“隐藏”原型getter / setter函数“在”构造函数getter / setters“背后”有什么价值吗? Eg, ns.Wheel.prototype.getWeight() is "hidden" behind the this.getWeight() method in the constructor. 例如, ns.Wheel.prototype.getWeight()被“隐藏”在构造函数的ns.Wheel.prototype.getWeight() this.getWeight()方法后面。

Also note how the prototype getter/setters add the unit for grams; 还要注意原型吸气剂/设置剂如何添加克数单位; ie, "g" unit. 即“ g”单位。 Eg, this.getWeight returns 1000, while ns.Wheel.prototype.getWeight returns 1000g. 例如, this.getWeight返回1000,而ns.Wheel.prototype.getWeight返回千克。

Wheels of swiss cheese are used in this example. 在此示例中使用瑞士奶酪轮。

(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.
  1. Any value to adding a second layer of abstraction, and using a prototype getter/setter function to invoke privileged constructor getter/setter functions? 添加第二个抽象层并使用原型getter / setter函数调用特权构造函数getter / setter函数有什么价值?

    In general, I would say no. 一般来说,我会拒绝。 It's much more memory efficient to have method exist on the prototype when possible, since methods set during instance construction will exist on each and every instance, while prototype methods need only be defined once, ever. 在可能的情况下,将方法存在于原型中会大大提高内存效率,因为在实例构造期间设置的方法将存在于每个实例中,而原型方法只需要定义一次。

  2. Any way to move one level up the prototype chain to instead invoke ns.Wheel.prototype.getWeight() 任何将原型链向上移动一级以调用ns.Wheel.prototype.getWeight()的方法

    If you want some method to have "private" access to variables defined inside of the constructor, those function must also be defined inside the constructor. 如果希望某些方法具有“私有”访问构造函数内部定义的变量的权限,则这些函数也必须在构造函数内部定义。 Function scope is set at declaration time. 功能范围是在声明时设置的。 Therefore, there is no way for a function defined outside of the constructor (eg, a prototype method) to have access to constructor-scope variables. 因此,无法在构造函数外部定义的函数(例如,原型方法)访问构造函数作用域变量。

    Because JavaScript functions are first-class objects, you can invoke the prototype method with call or apply : ns.Wheel.prototype.setWeight.call(this, 1000) (where the first argument sets the this value for the function being invoked, and further arguments are actual function arguments). 因为JavaScript函数是一类对象,所以您可以使用callapply调用原型方法: ns.Wheel.prototype.setWeight.call(this, 1000) (其中第一个参数为正在调用的函数设置this值,以及其他参数是实际的函数参数)。

  3. Any value to "hiding" the prototype getter/setter functions "behind" the constructor getter/setters? 对“隐藏”原型getter / setter函数“在”构造函数getter / setters“背后”有什么价值吗?

    In your case, ns.Wheel.prototype.getWeight (and its corresponding setter) are never used. 在您的情况下,永远不会使用ns.Wheel.prototype.getWeight (及其相应的设置器)。 When getWeight2 calls this.getWeight() , that resolves to the instance-level function, and there is no need to look up the prototype chain for the prototype method. getWeight2调用this.getWeight() ,它将解析为实例级别的函数,并且无需查找原型方法的原型链。

    The only value I can see might be if you conditionally shadowed some prototype method with an instance method, and in other cases let the prototype method show through. 我能看到的唯一值可能是您是否有条件地用实例方法遮盖了某些原型方法,而在其他情况下让该原型方法显示出来。 However, if you want that prototype method to have access to constructor-scope variables, you're out luck, as explained in point #2. 但是,如果您希望该原型方法可以访问构造函数作用域变量,那么您会很不幸,如第2点所述。 For example: 例如:

     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; } 

    This isn't a great example (it works better with simple values like numbers, instead of functions), but it's the only "useful" example of prototype shadowing I could think of. 这不是一个很好的例子(它对数字之类的简单值而不是函数更有效),但这是我能想到的唯一的“有用”原型阴影实例。

I strongly endorse the second comment above, which advises against using private variables at all. 我强烈支持上面的第二条评论,建议不要使用私有变量。 They waste memory, as described in my first point, by requiring an method that uses them to be defined on every instance. 如第一点所述,它们浪费内存,因为需要在每个实例上定义使用它们的方法。 By trying to simulate private variables, you squander the power of prototypal inheritance. 通过尝试模拟私有变量,您浪费了原型继承的力量。 Instead (as mentioned in the comments), make all your variables public and designate your "private" variables with a leading underscore. 而是(如评论中所述),将所有变量公开,并在下划线前指定“私有”变量。

Any value to adding a second layer of abstraction, and using a prototype getter/setter function to invoke privileged constructor getter/setter functions? 添加第二个抽象层并使用原型getter / setter函数调用特权构造函数getter / setter函数有什么价值? See ns.Wheel.prototype.getWeight2() and ns.Wheel.prototype.setWeight2() below. 请参见下面的ns.Wheel.prototype.getWeight2()和ns.Wheel.prototype.setWeight2()。

Why not? 为什么不? Well, keep in mind that calling functions is expensive, so if it's only to add 'g' at the end you can consider doing it manually if you want to gain some microseconds. 好吧,请记住,调用函数是昂贵的,因此,如果仅在末尾添加'g' ,则您可以考虑手动获取,如果要获得一些微秒。

The call to swiss.getWeight() invokes the this.getWeight() method in the constructor. 调用swiss.getWeight()会调用构造函数中的this.getWeight()方法。 Any way to move one level up the prototype chain to instead invoke ns.Wheel.prototype.getWeight()? 有什么办法将原型链向上移动一级来调用ns.Wheel.prototype.getWeight()吗?

Yes, you can: 是的你可以:

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

Any value to "hiding" the prototype getter/setter functions "behind" the constructor getter/setters? 对“隐藏”原型getter / setter函数“在”构造函数getter / setters“背后”有什么价值吗? Eg, ns.Wheel.prototype.getWeight() is "hidden" behind the this.getWeight() method in the constructor. 例如,ns.Wheel.prototype.getWeight()被“隐藏”在构造函数的this.getWeight()方法后面。

It depends on the situation. 这取决于实际情况。 In your case I would use different names to avoid "hiding". 在您的情况下,我将使用其他名称来避免“隐藏”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM