javascript私有函数访问公共变量

Posted

技术标签:

【中文标题】javascript私有函数访问公共变量【英文标题】:javascript private function access public variable 【发布时间】:2012-05-29 22:24:27 【问题描述】:

我有这门课:

function ctest() 
    this.var1 = "haha";
    this.func1 = function() 
        alert(this.var1);
        func2();
        alert(this.var1);
    
    var func2 = function() 
        this.var1 = "huhu";
    

并称之为:

    var myobj = new ctest();
    myobj.func1();

不应该第二个警报会弹出“huhu”吗? func2 是私有的,不能访问 var1 的公共变量吗?

如果私有函数无法访问公共变量,我该怎么办?

提前致谢!

【问题讨论】:

另外,这里没有private这样的东西。 这个obj.func1()应该是myobj.func1() @forsvarir 是的,应该 - 我为他修好了。 阅读developer.mozilla.org/en/javascript/Reference/Operators/this 了解this 的工作原理。 【参考方案1】:

您需要提供调用func2的上下文:

this.func1 = function() 
    alert(this.var1);
    func2.call(this);
    alert(this.var1);

如果没有上下文,调用将使用全局对象(即window) - 当您运行当前代码时,您应该会看到在两个警报之间创建了window.var1

【讨论】:

如果我按照您的建议进行操作,则表明 func2() 不是函数 @MIrrorMirror 啊,嗯,是的 - 等等! 那行不通:func2 是私有变量,而不是属性。 @xdazz 现已修复 - 您必须使用 .call 将上下文添加到本地范围的函数。 @MIrrorMirror 否,.call 的第一个参数设置函数内隐含的this 值。【参考方案2】:

函数与实例无关,因此您对 func2 的调用最终会导致 this 没有指向预期实例的调用。

您可以修复调用以包含上下文:

function ctest() 
    this.var1 = "haha";
    this.func1 = function() 
        alert(this.var1);
        func2.call(this);
        alert(this.var1);
    
    var func2 = function() 
        this.var1 = "huhu";
    

或者您可以保留一个带有所需对象引用的变量:

function ctest() 
    var that = this;
    this.var1 = "haha";
    this.func1 = function() 
        alert(this.var1);
        func2();
        alert(this.var1);
    
    var func2 = function() 
        that.var1 = "huhu";
    

【讨论】:

您能否提供有关此主题的进一步阅读,因为我想知道哪个是最佳实践以及为什么 @InsOp 我建议阅读 MDN 关于“this”关键字的帮助:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…【参考方案3】:

另一种选择是使用Function.bind

function ctest() 
    this.var1 = "haha";
    this.func1 = function() 
        alert(this.var1);
        func2();
        alert(this.var1);
    
    var func2 = function() 
        this.var1 = "huhu";
    .bind(this);

请注意,浏览器对此的支持并不完美。

【讨论】:

为什么要同时使用that .bind() @Alnitak:糟糕的复制和粘贴【参考方案4】:

在 JS 中没有私有这样的东西,但是你可以使用 closures 来玩作用域。

例如,假设在您的示例中,您不需要将 var1 公开为公共财产。您可以轻松地重写您的代码,如下所示:

function ctest() 
    var var1 = "haha";

    this.func1 = function() 
        alert(var1);
        func2();
        alert(var1);
    

    var func2 = function() 
        var1 = "huhu";
    

因为func1func2 共享相同的范围——它们在相同的函数中定义,ctest——它们可以访问相同的变量。当然,在这种情况下你没有暴露var1,所以:myobj.var1 将是undefined

如果你想让var1作为属性公开,那么你需要bindfunc2到你在构造函数中创建的对象实例:

function ctest() 
    this.var1 = "haha";
    this.func1 = function() 
        alert(this.var1);
        func2();
        alert(this.var1);
    
    var func2 = function() 
        this.var1 = "huhu";
    .bind(this);

否则func2 将具有不同的上下文对象 (this)。如果浏览器不支持 bind 并且您不想使用 shim(如上面的链接所示),您可以再次利用闭包:

function ctest() 
    this.var1 = "haha";
    this.func1 = function() 
        alert(this.var1);
        func2();
        alert(this.var1);
    
    var context = this;
    var func2 = function() 
        context.var1 = "huhu";
    

IMVHO 不那么优雅。

【讨论】:

【参考方案5】:
function ctest() 
    this.var1 = "haha";
    this.func1 = function() 
        alert(this.var1);
        func2(this);
        alert(this.var1);
    
    var func2 = function(obj) 
        obj.var1 = "huhu";
    

还有其他方法可以解决这个问题,请查看其他答案:)

【讨论】:

@Alnitak 但这不会有问题,obj 是参数。

以上是关于javascript私有函数访问公共变量的主要内容,如果未能解决你的问题,请参考以下文章

从 javascript 类中的“私有”方法访问“公共”方法

Java子类访问父类的私有成员变量

javascript 仿面向对象编程实例代码(私有,公共变量。。。)

让公共成员变量访问 C++ 中同一类的私有成员

java内部私有类的构造函数

私有静态变量