我试图通过此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
答案 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 );
}