Javascript修改私有函数

时间:2016-09-27 14:20:39

标签: javascript class oop properties private-functions

我用JavaScript编写了一个类,我试图在私有函数中修改我的一个公共属性。

以下是我的代码示例:

MyClass = function(callback){

    this.tabs = [];
    var tabs_callback = function(){};

    this.setTabsCallback = function(callback) {
        tabs_callback = callback;
    }

    var _doStuff = function(callback) {

        // doing stuff

        this.tabs = [1, 2, 3];

        console.log("Inside doStuff");
        console.log(this.tabs);

        tabs_callback();
    }

    this.doStuff = function() {
        _doStuff();
    }
}


var myObject = new MyClass();

myObject.setTabsCallback(function () {

    console.log("Inside callback");
    console.log(myObject.tabs);
});

myObject.doStuff();

以下是我在控制台中获得的内容:

Inside doStuff
[ 1, 2, 3 ]
Inside callback
[]

为什么我无法从回调函数中看到我的修改?

4 个答案:

答案 0 :(得分:1)

this keyword。使用箭头函数是防止许多这些问题的好方法:

var _doStuff = (callback) => { ...

但你仍需要了解它。

答案 1 :(得分:1)

默认情况下,JS不使用词汇上下文绑定,当您调用普通函数时,this默认为window(如果您处于严格模式,则默认为null

有很多方法可以避免它:如上所述,您可以将this保存到变量中。它将在100%的情况下起作用。

此外,您可以使用Function#bind方法将_doStuff显式绑定到上下文:在_doStuff = _doStuff.bind(this)初始化之后执行类似_doStuff.bind(this)()的操作,或者您可以将其称为bind。 IE9之前的IE(以及其他一些浏览器,我不太确定)不支持this

最后,您可以使用箭头功能,如上所述:它们使用词法绑定,import decimal count = pi = a = b = c = d = val1 = val2 = decimal.Decimal(0) #Initializing the variables decimal.getcontext().prec = 25 #Setting percision while (decimal.Decimal(count) <= decimal.Decimal(100)): a = pow(decimal.Decimal(-1), decimal.Decimal(count)) b = ((decimal.Decimal(2) * decimal.Decimal(count)) + decimal.Decimal(1)) c = pow(decimal.Decimal(1/5), decimal.Decimal(b)) d = (decimal.Decimal(a) / decimal.Decimal(b)) * decimal.Decimal(c) val1 = decimal.Decimal(val1) + decimal.Decimal(d) count = decimal.Decimal(count) + decimal.Decimal(1) #The series has been divided into multiple small parts to reduce confusion count = a = b = c = d = decimal.Decimal(0) #Resetting the variables while (decimal.Decimal(count) <= decimal.Decimal(10)): a = pow(decimal.Decimal(-1), decimal.Decimal(count)) b = ((decimal.Decimal(2) * decimal.Decimal(count)) + decimal.Decimal(1)) c = pow(decimal.Decimal(1/239), decimal.Decimal(b)) d = (decimal.Decimal(a) / decimal.Decimal(b)) * decimal.Decimal(c) val2 = decimal.Decimal(val2) + decimal.Decimal(d) count = decimal.Decimal(count) + decimal.Decimal(1) #The series has been divided into multiple small parts to reduce confusion pi = (decimal.Decimal(16) * decimal.Decimal(val1)) - (decimal.Decimal(4) * decimal.Decimal(val2)) print(pi) 将与您期望的相同。自ES6以来,箭头功能可用,但是,我想,如果你正在制作这样的构造函数,它不是ES6。

答案 2 :(得分:1)

通过类似

的函数调用_doStuf
this.doStuff = function() {
                 _doStuff();
               }

_doStuff绑定到全局对象。因此,您应该在调用this函数时将其定义绑定到.call(this)或使用_doStuff。因此,如下修改代码将有所帮助;

MyClass = function(callback){

    this.tabs = [];
    var tabs_callback = function(){};

    this.setTabsCallback = function(callback) {
        tabs_callback = callback;
    }

    var _doStuff = function(callback) {

        // doing stuff

        this.tabs = [1, 2, 3];

        console.log("Inside doStuff");
        console.log(this.tabs);

        tabs_callback();
    } // <<< you can either use .bind(this) here 

    this.doStuff = function() {
        _doStuff.call(this);  // <<< or use .call(this) here to bind _doStuff to the this
    }
}


var myObject = new MyClass();

myObject.setTabsCallback(function () {

    console.log("Inside callback");
    console.log(myObject.tabs);
});

myObject.doStuff();

答案 3 :(得分:1)

由于_doStuff被定义为函数,因此它具有自己的this上下文,这就是您无法访问在私有函数之外定义的this.tabs的原因。

有两种简单的方法可以解决这个问题。

首先,您可以创建一个私有变量,该变量在函数外部保存对this的引用:

...
var that = this;
var _doStuff = function(callback) {
    // inside _doStuff, use "that" instead of "this"
...

或者,第二,你可以使用箭头功能。箭头函数是Javascript的一个相对较新的补充。它们不会使用自己的this引用创建单独的上下文,因此当您使用this对象时,它仍将引用与函数外部相同的对象,因此您的函数将正常工作:

....
var _doStuff = (callback) => {
    // now _doStuff doesn't create a new "this" object, so you can still access the one from outside
...