简体   繁体   English

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

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

I am trying to understand Encapsulation through this 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; 

According to the link meth1() accessed through this.meth2 should work, but to my surprise i got undefined. 根据通过this.meth2访问的链接meth1()应该可以工作,但令我惊讶的是我未定义。

Could you please shed some light on what is happening here. 您能否说明一下这里发生的事情。 I am using IE 9 for this and getting 我正在为此使用IE 9

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

The code in Rajesh's answer is great but I would like to add a couple words about encapsulation in JavaScript and the behaviour of "this". Rajesh的答案中的代码很棒,但是我想补充一些有关JavaScript封装和“ this”行为的信息。

First of all, in my example I won't be using 'new' as it is evil. 首先,在我的示例中,我不会使用“ new”,因为它很邪恶。 'new' forces you to use this inside the function and its behaviour isn't really transparent. “新”强制您在函数内部使用此函数,并且其行为并不是真正透明的。 Your code itself and the usage of scope will be much easier to understand without it. 没有它,您的代码本身和范围的用法将更容易理解。

There are two important facts about referring to different variables inside the code: 关于在代码中引用不同的变量有两个重要的事实:

1) 'this' points to the object inside which it is used. 1)'this'指向使用它的对象。 This can lead to confusion as functions are first-class objects but 'this' inside your subfunctions points to the parent function (Test()). 这可能会导致混淆,因为函数是一类对象,但是子函数中的“ this”指向父函数(Test())。 Don't use 'this' inside functions to avoid confusion, use it inside objects. 不要在函数内部使用“ this”以避免混淆,请在对象内部使用它。

2) JavaScript has function scope and this is how encapsulation basically works. 2)JavaScript具有功能范围,这就是封装的基本原理。 Inner functions can see variables declared in outer objects. 内部函数可以看到在外部对象中声明的变量。 Re-declaring variables inside an inner function with the same name overwrites the outer variable instead of creating an inner copy with higher precedence. 在内部函数中用相同的名称重新声明变量会覆盖外部变量,而不是创建优先级更高的内部副本。

If you build your code without using 'new' and 'this' inside functions, your question should be self-explanatory: 如果在不使用函数内部使用“ 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();

Note how prop1 and display_prop1 cannot be changed from outside the build_test_object code. 请注意,如何不能从build_test_object代码外部更改prop1和display_prop1。 Even if test_object.disp_prop is replaced, they will remain intact (this is important if other methods inside build_test_object use prop1 or display_prop1). 即使替换了test_object.disp_prop,它们也将保持不变(如果build_test_object中的其他方法使用prop1或display_prop1,则这一点很重要)。 This is known as a closure: build_test_object() has already resolved and whatever was inside its function scope without being exposed is immutable. 这被称为闭包:build_test_object()已解决,其函数范围内的任何未暴露的东西都是不可变的。

For a comprehensive explanation of scope, closures and proper encapsulation methods in JavaScript I recomment "JavaScript: The Good Parts" by Douglas Crockford as this is a bit beyond the scope of one question on this site. 对于JavaScript的范围,闭包和正确的封装方法的全面说明,我建议道格拉斯·克罗克福德(Douglas Crockford)撰写的“ JavaScript:The Good Parts”,因为这超出了该站点上一个问题的范围。

in addition to @Michael's answer, when you try to make a function as a class, remember to return value. 除了@Michael的答案外,当您尝试将函数作为类时,请记住要返回值。 This value will be publicly available. 此值将公开可用。 In a class structure, var result3 = tc.prop1; 在类结构中, var result3 = tc.prop1; should return undefined . 应该返回undefined Only way to access it should be a function. 访问它的唯一方法应该是函数。 Following is a representation 以下是代表

 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) 

You are successfully calling meth1() from inside this.meth2() . 成功从this.meth2()内部调用meth1() this.meth2() That's where you are seeing the Inside meth1one message displayed by the console.log() inside meth1() . 那是您Inside meth1one console.log()内部meth1() console.log()显示的Inside meth1one消息的地方。

The undefined value you see on the next line of the log is simply because you are trying to display the value returned by meth1() , but meth1() does not return a value! undefined你的日志的下一行看到了价值仅仅是因为你试图显示返回的值meth1()meth1()没有返回值! Therefore its return value is undefined , as displayed by the console.log() in this.meth2() . 因此,其返回值是undefined ,如this.meth2() console.log()所显示。

Debugging Tip 调试技巧

I suggest stepping through your code in the JavaScript debugger instead of just relying on console.log() . 我建议在JavaScript调试器中逐步执行代码,而不仅仅是依赖console.log() Single step into each function and each line of code. 一步步进入每个函数和每一行代码。 This will help you understand the flow of control in the code. 这将帮助您了解代码中的控制流。

To make this easier, write your functions on multiple lines instead of making them one-liners, eg: 为了使此过程更容易,请多行编写函数,而不要使它们成为一排直线,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM