2014-06-21 76 views
0

此示例實現了矩形的私有變量。變量myLength和myWidth對於不同的實例是不同的。那麼爲什麼這不是建議的方法?Javascript:通過返回匿名對象實現私有變量

var rectangle = function() { 
    var myLength = 8; 
    var myWidth = 6; 

    var getMyLength = function() { 
     return myLength; 
    }; 

    var setMyLength = function (value) { 
     myLength = value; 
    }; 

    var getMyWidth = function() { 
     return myWidth; 
    }; 

    var setMyWidth = function (value) { 
     myWidth = value; 
    }; 

    var drawFigure = function() { 
     console.log("Draw invoked for figure: " + 
      getMyLength() + " * " + getMyWidth()); 
    }; 

    return { 
     getMyLength: getMyLength, 
     setMyLength: setMyLength, 
     getMyWidth: getMyWidth, 
     setMyWidth: setMyWidth, 
     drawFigure: drawFigure 
    } 
}; 

然後我們使用它,如下所示:

var myRectangle = new rectangle(); 

myRectangle.drawFigure();   // Draw invoked for figure: 8 * 6 

myRectangle.setMyLength(3); 

myRectangle.setMyWidth(5); 

myRectangle.drawFigure();   // Draw invoked for figure: 3 * 5 

var myRectangle1 = new rectangle(); 

myRectangle1.drawFigure();   // Draw invoked for figure: 8 * 6 
+4

*「那麼,爲什麼這不是推薦的方法?」*誰說不推薦?當您需要保護變量時,這是一種非常常見的方法。 –

+1

......和'new rectangle();'可以是'rectangle();'。沒有意見分配一個新的對象,如果你要忽略它並返回一個不同的對象。 –

+0

@cookiemonster謝謝。我看到很多使用this.length和this.width而不是var的例子。爲什麼你使用this.methods呢? 我用來學習的一個示例頁面:http://phrogz.net/JS/classes/OOPinJS.html – bschandramohan

回答

2

在我看來私有變量是高估了。你真的需要隱藏程序員的東西嗎?不會。即使你公開所有的私人變數,它會產生什麼樣的變化?事實上,我主張讓一切公開,因爲:

  1. 這將使調試更容易。如果你的對象是console.log,那麼你可以檢查它的公共屬性,這使得調試更容易,因爲你可以看到對象的狀態。
  2. 您不需要創建不必要的關閉。如果你想要一個私有變量,也希望它可以通過公共方法訪問,那麼你必須創建一個閉包(每個實例一個)。如果你公開你的屬性,那麼你不需要關閉。你可以把這些方法放在原型上。因此,每個類只有一個方法,由所有實例共享。
  3. 您不需要創建不必要的getter和setter。製作變量private並允許任何人使用getter和setter函數對其進行修改有什麼意義?你也可以讓變量公開。

    getter和setter方法,在我的愚見,是唯一有用的幻影的屬性:

    var Person = defclass({ 
        constructor: function (firstName, lastName) { 
         this.firstName = firstName; 
         this.lastName = lastName; 
        }, 
        getFullName: function() { 
         return this.firstName + " " + this.lastName; 
        }, 
        setFullName: function (fullName) { 
         var name = fullName.split(" "); 
         this.firstName = name[0]; 
         this.lastName = name[1]; 
        } 
    }); 
    

因此,在我看來,你應該寫你的Rectangle類,如下所示:

var Rectangle = defclass({ 
    constructor: function (width, height) { 
     this.width = width; 
     this.height = height; 
    } 
}); 

然後我們使用它如下:

var rectA = new Rectangle(8, 6); 

console.log(rectA);    // { width: 8, height: 6 } 

rectA.width = 3; 
rectA.height = 5; 

console.log(rectA);    // { width: 3, height: 5 } 

var rectB = new Rectangle(8, 6); 

console.log(rectB);    // { width: 8, height: 6 } 

最後,defclass定義:

function defclass(prototype) { 
    var constructor = prototype.constructor; 
    constructor.prototype = prototype; 
    return constructor; 
} 

所以這是你應該在JavaScript中創建對象的方式只是我的兩分錢。

+1

當您需要限制/健全性檢查正在設置的值時,吸氣劑和吸附劑也很有用。 –

+1

這取決於您是否希望驗證邏輯成爲您班級的一部分。在我看來,驗證邏輯不屬於類本身。簡單地假設對對象的任何修改都是有效的,而不是防禦性的。我寧願寫一個單獨的函數進行驗證:'if(isValid(value))object.property = value;'。在這樣做的時候,你將驗證邏輯與setter分開,允許你在其他地方重用它。此外,您還可以明確自我驗證,減少班級的複雜性並減少它們之間的耦合。 –

+2

從你的公共API隱藏實現。在其他語言中,你的程序依賴於大量的其他模塊,它只需要一個被黑客攻擊並依賴實現的壞程序員。當模塊更新時,即使更新的部分具有相同的公共API,也可能會破壞整個事物。話雖如此;我也不太用它 – HMR

相關問題