簡體   English   中英

使用getter和setter在JavaScript中封裝

[英]Encapsulation in JavaScript with getter and setter

我意識到這已被問到但是已經研究過並且失敗了 - 對不起!

我想盡可能簡單地在JS中實現封裝。 我意識到班里的任何'var'都是私有的。

我只是不確定如何獲取和設置任何私有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>

在構造函數中聲明的任何var都不會存在於該構造函數之外。 您需要連接東西, 是為了對原型方法才能看到它。 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就像普通屬性一樣,它會調用你的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM