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

How to access private variable using a public method within same object in javascript?

我试图通过这个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;

根据通过 this.meth2 访问的 link meth1() 应该可以工作,但令我惊讶的是我没有定义。

能否请您说明一下这里发生的事情。我为此使用 IE 9 并获得

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

this.meth2()内部成功调用了meth1()。这就是您在 meth1().

中看到 console.log() 显示的 Inside meth1one 消息的地方

您在日志的下一行看到的 undefined 值仅仅是因为您试图显示由 meth1() 编辑的 return 值,但是 meth1()没有 return 值!因此它的 return 值为 undefined,如 this.meth2() 中的 console.log() 所示。

调试技巧

我建议在 JavaScript 调试器中单步调试您的代码,而不是仅仅依赖 console.log()。单步执行每个函数和每一行代码。这将帮助您理解代码中的控制流。

为了使这更容易,请将您的函数写在多行而不是一行中,例如:

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

除了@Michael 的回答之外,当您尝试将函数设为 class 时,请记住 return 值。该值将公开可用。在 class 结构中,var result3 = tc.prop1; 应该 return 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)

Rajesh 的回答中的代码很棒,但我想补充几句关于 JavaScript 中的封装和 "this" 的行为。

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

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

1) 'this'指向使用它的对象。这可能会导致混淆,因为函数是 first-class 对象,但子函数内部的 '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();

请注意 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",因为这有点超出了本网站上一个问题的范围。