如何在javascript中使用同一对象内的公共方法访问私有变量?

时间:2015-12-24 07:35:30

标签: javascript encapsulation

我试图通过此link

了解封装

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;

根据通过meth1()访问的链接this.meth2应该有效,但令我惊讶的是我未定义。

请您详细说明这里发生的事情。我正在使用IE 9来获取

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

3 个答案:

答案 0 :(得分:2)

Rajesh的答案中的代码很棒,但我想补充一些关于JavaScript封装和“this”行为的话。

首先,在我的例子中,我不会使用'new',因为它是邪恶的。 'new'强制你在函数内部使用它,它的行为并不是真正透明的。没有它,您的代码本身和范围的使用将更容易理解。

关于在代码中引用不同变量,有两个重要的事实:

1)'this'指向使用它的对象。这可能会导致混淆,因为函数是一等对象,但子函数内的“this”指向父函数(Test())。不要在函数内使用'this'以避免混淆,在对象内部使用它。

2)JavaScript具有功能范围,这就是封装基本上如何工作的方式。内部函数可以查看外部对象中声明的变量。在具有相同名称的内部函数内重新声明变量会覆盖外部变量,而不是创建具有更高优先级的内部副本。

如果你在函数内部不使用'new'和'this'来构建代码,那么你的问题应该是不言自明的:

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();

注意无法从build_test_object代码外部更改prop1和display_prop1。即使替换了test_object.disp_prop,它们也将保持不变(如果build_test_object中的其他方法使用prop1或display_prop1,这很重要)。这被称为闭包:build_test_object()已经解决,并且在没有公开的情况下,其功能范围内的任何内容都是不可变的。

为了全面解释JavaScript中的范围,闭包和正确的封装方法,我推荐Douglas Crockford的“JavaScript:The Good Parts”,因为这有点超出了本网站上一个问题的范围。

答案 1 :(得分:1)

除了@ Michael的回答,当你尝试将一个函数作为一个类时,记得返回值。该值将公开提供。在类结构中,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)

答案 2 :(得分:0)

meth1()内成功呼叫this.meth2()。您可以在Inside meth1one内看到console.log()显示的meth1()消息。

您在日志的下一行看到的undefined值仅仅是因为您尝试显示meth1()返回的值,但meth1()未返回值!因此,其返回值为undefined,由console.log()中的this.meth2()显示。

调试提示

我建议您在JavaScript调试器中单步执行代码,而不是仅依靠console.log()。单步进入每个函数和每行代码。这将有助于您了解代码中的控制流程。

为了简化这一过程,请在多行上编写函数,而不是将它们作为单行,例如:

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