2015-12-24 15 views
2

我想通過這個link如何使用JavaScript中的同一對象內的公共方法訪問私有變量?

function Test() { 
 
    var prop1 = "one"; 
 
    this.prop2 = "two"; 
 

 
    function meth1() { 
 
    console.log("Inside meth1" + prop1); 
 
    } 
 

 
    this.meth2 = function() { 
 
    console.log(this.prop2 + "................, " + meth1()); 
 
    }; 
 

 
    this.meth4 = function(val) { 
 

 
    prop1 = val; 
 

 
    console.log("inside meth4" + prop1); 
 
    } 
 
} 
 

 
var tc = new Test(); 
 
var result1 = tc.meth2(); 
 
var result3 = tc.prop1;

瞭解封裝根據通過this.meth2訪問應該工作的聯繫meth1(),但出乎我的意料,我得到未定義。

您能否介紹一下這裏發生的事情。我使用的IE 9,這和越來越

LOG: Inside meth1one 
LOG: two................, undefined 

回答

1

除了@邁克爾的答案,當你嘗試做一個函數爲一類,記得要回報價值。該值將公開可用。在班級結構中,var result3 = tc.prop1;應返回undefined。只有訪問它的方法應該是一個功能。以下是表示

function Test() { 
 
    
 
    // To hold context as object inside functions 
 
    var self = this; 
 
    self.prop1 = "one"; 
 
    self.prop2 = "two"; 
 

 
    // method to access prop1 
 
    function meth1() { 
 
    return self.prop1; 
 
    } 
 

 
    // method to access prop2 
 
    function meth2() { 
 
    return self.prop2; 
 
    }; 
 
    
 
    // Properties that will be publically available. 
 
    // Never add private variables here. 
 
    return{ 
 
    "meth1":meth1, 
 
    "meth2":meth2 
 
    } 
 
} 
 

 
var tc = new Test(); 
 
var result1 = tc.meth1(); // Should be "one" 
 
var result2 = tc.prop1; // Should be "undefined". Private property 
 
var result3 = tc.meth2(); // Should be "two" 
 

 
console.log(result1,result2,result3)

+0

Downvoter,如果我在答案中遺漏了某些東西,請隨時發表評論。會真的很感激它。 – Rajesh

0

成功地從裏面this.meth2()調用meth1()。這就是你在meth1()內看到console.log()顯示的Inside meth1one消息的地方。

您在日誌的下一行看到的undefined值僅僅是因爲您試圖顯示由meth1()返回的值,但meth1()未返回值!因此其返回值爲undefined,如this.meth2()中的console.log()所示。

調試提示

我建議通過JavaScript調試器的代碼,而不是僅僅依靠console.log()步進。單步進入每個功能和每行代碼。這將幫助您瞭解代碼中的控制流程。

爲了更方便,多條線路上,而不是把單行寫你的功能,例如:

function meth1() { 
    console.log("Inside meth1" + prop1); 
} 
2

在Rajesh的答案的代碼是偉大的,但我想補充的關於JavaScript的封裝和「本」行爲的兩句話。

首先,在我的例子中,我不會使用'新',因爲它是邪惡的。 '新'迫使你在函數內部使用它,它的行爲並不真正透明。沒有它,你的代碼本身和範圍的使用將更容易理解。

大約有參照不同的變量的代碼內的兩個重要事實:

1)「這」指向內部使用它的對象。這可能導致混淆,因爲函數是第一類對象,但是子函數中的「this」指向父函數(Test())。不要在函數內使用'this'以避免混淆,請在對象內部使用它。

2)JavaScript具有函數範圍,這就是封裝如何工作的。內部函數可以看到外部對象中聲明的變量。在同名的內部函數中重新聲明變量會覆蓋外部變量,而不是創建具有更高優先級的內部副本。

如果你建立你的代碼,而無需使用「新」和「這個」裏面的功能,你的問題應該是不言自明:

function build_test_object() { 

    //This object will house all the functionality we will need to return 
    var that = {}; 

    //This is a variable visible only while executing build_test_object 
    var prop1 = "one"; 

    //display_prop1 is a function that is visible only inside build_test_object 
    //This way it will be protected after you use build_test_object: the function itself cannot be changed even if the object is altered 
    var display_prop1 = function() { 
     window.alert(prop1); 
    } 

    //And now we assign this function to the object we will return. 
    that.disp_prop = display_prop1; 

    //Returning the finished object 
    return that; 
} 

//Create the object 
var test_object = build_test_object(); 
//Display the property 
test_object.disp_prop(); 

注意如何PROP1和display_prop1不能從build_test_object碼外修改。即使替換test_object.disp_prop,它們也會保持不變(如果build_test_object中的其他方法使用prop1或display_prop1,則這很重要)。這就是所謂的閉包:build_test_object()已經解決了,而且它的函數範圍內沒有被暴露的東西是不可變的。

有關JavaScript中範圍,封閉和適當封裝方法的全面說明,我推薦Douglas Crockford編寫的「JavaScript:The Good Parts」,因爲這有點超出了本網站上某個問題的範圍。

+0

謝謝恭維。在這種方法中,是否有使用'prototype'的方法?就像我定義一個通用函數'setProperty(propName,propValue)'一樣 – Rajesh

相關問題