簡體   English   中英

javascript私有函數訪問公共變量

[英]javascript private function access public variable

我有這堂課:

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公共變量?

如果私有函數無法訪問公共變量,我該怎么辦?

提前致謝!

您需要為func2調用提供上下文:

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

如果沒有上下文,調用將使用全局對象(即window ) - 您應該看到在運行當前代碼時,在兩個警報之間創建了window.var1

功能不依賴於實例,因此您的調用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";
    }
}

另一種選擇是使用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);
}

請注意,瀏覽器對此的支持並不完美。

在JS中沒有private這樣的東西,但你可以使用閉包來使用范圍。

比方說,例如,在您的示例中,您不需要將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公開為屬性,那么您需要 func2 綁定到您在構造函數中創建的對象實例:

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並且您不想使用填充程序(如上面的鏈接所示),則可以再次利用這些閉包:

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不那么優雅。

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

並有其他方法來解決這個問題,檢查其他答案:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM