【问题标题】:Encapsulation in JavaScript with getter and setter用 getter 和 setter 封装在 JavaScript 中
【发布时间】:2018-05-05 10:20:59
【问题描述】:

我知道这已经被问过了,但已经研究过并且失败了 - 抱歉!

我想尽可能简单地在 JS 中实现封装。我意识到课堂上的任何“var”都是私有的。

我只是不确定如何获取和设置任何私有变量的值。在下面的示例中,GETTING 和 SETTING 'color' 的接口方法不起作用,因为这些函数无法访问对象的私有 'color' 属性。我找不到一个清楚的例子来告诉我如何实现它。

我什至不确定使用“.prototype”是将这些方法添加到类中的最佳方式。

谢谢!

<button onclick="testOOP()">Click me</button>

<script>
//<!-- 
function testOOP(){
var v1 = new vehicle(4, "red"); //setting new values during instantiation
var v2 = new vehicle(2, "blue");
showVehDetails(v1);
showVehDetails(v2);
v2.wheels=1;            //demonstrating no encapsulation
showVehDetails(v2);
v2.setcolour("orange");     //using an interface - fails
showVehDetails(v2);
}

    function showVehDetails(v){
        document.write("This vehicle is " + v.getcolour() + " and has " + v.getwheels() + " wheels.<br/>");
    }

    //*************'vehicle' - Class definition**************
    function vehicle(thewheels, thecolour){
        this.wheels = thewheels;            //public property
        var colour = thecolour;             //private property
    }   
    vehicle.prototype = {
        constructor: vehicle,
        getcolour: function(){
            return this.colour;         //but how to create a GETTER for colour?
        },
        getwheels: function(){
            return this.wheels;
        },
        setwheels: function(newwheels){
            this.wheels = newwheels;
        },
        setcolour: function(newcolour){   //and how to create a SETTER for colour?
            this.colour = newcolour;
        }
    }
    //************End class definition************************
   //-->
 </script>

【问题讨论】:

  • mmm 在 javascript 中不存在真正的类,总是原型一个 inteherance
  • 如果要启用获取和设置,只需将它们设为公共属性?!
  • @Bergi,这是一个学术练习,旨在找到使用 JavaScript 演示封装的最简单方法。我通常会使用公共属性或 _properties。

标签: javascript encapsulation setter getter


【解决方案1】:

在构造函数中声明的任何vars 都不会存在于该构造函数之外。您需要将东西附加到 this 以便原型方法可以看到它。 JavaScript 没有私有成员的概念。

function Vehicle(thewheels, thecolour){
  this.wheels = thewheels;
  this.colour = thecolour;
}

Vehicle.prototype = {
  getColour: function() {
    return this.colour;
  }
  // etc
};

...但是您必须问自己,在这些成员周围放置 getter/setter 有什么好处?在 JavaScript 中很少使用 getter/setter 模式。通常你只是创建公共成员。为成员使用 _ 之类的前缀是表示“我知道这是可访问的,但你不应该直接修改它”的典型方式。

如果您确实想让事情真正“私有化”,则需要使用闭包做一些技巧:

function Vehicle(theWheels, theColor) {
  return {
    getColour: function() { return theColor; },
    setColour: function(value) { theColor = value; }
  };
}

...但是这种方法的缺点是每个Vehicle 对象都有自己的这些函数的副本;您不会获得原型的内存优势。

更新

还要注意:如果您确实想通过包装方法来触发更改成员的逻辑,那么在现代 JS 中创建 getter 和 setter 有更好的方法:

function Vehicle(theWheels, theColor) {
  this._wheels = theWheels;
  this._color = theColor;
}

Vehicle.prototype = {
  get color() { return this._color; },
  set color(value) { this._color = value; console.log('Changed color'); },

  get wheels() { return this._wheels; },
  set wheels(value) { this._wheels = value; }
}

调用者只是像普通属性一样访问.wheels.color,它会调用你的方法。

【讨论】:

  • 自己的方法大部分可以被回收,只有激活信封需要在每个实例中都是唯一的,因此没有像这里预期的那样存在内存缺点。
  • 我查看了“get”和“set”,但它们似乎只适用于公共属性。在“真实”世界中,我将使用它们;但在这个学术练习中我不能!
  • @Jacob 谢谢!这很好用——即使我不明白将这些函数放在“返回”中是如何工作的。有什么方法可以结合您提供的两种解决方案?即使用带有私有(不仅仅是_hidden)属性的'get'和'set'?我在这里发布了一个后续问题:stackoverflow.com/questions/47431014/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2019-01-30
相关资源
最近更新 更多