2
function MyClass() {
    this.a = "me a";
    this.b = "me b";
};

MyClass.prototype.changeB = function(callback) {
    this.a = "now me A";
    doAnotherFunction(function(err, data) {
        this.b = "now me B";
    callback(null, this.b);});
};

function doAnotherFunction(callback) {
    callback(null, null);
};

main();

function main() {
    var myclass = new MyClass();
    myclass.changeB(function(err, data) {
    console.log("B: " + myclass.b + ", data: " + data);});
    console.log(JSON.stringify(myclass));
}


When this runs:
B: me b, data: now me B
{"a":"now me A","b":"me b"}

对我放轻松,我是 javascript 新手并在这里发帖。

我的问题是为什么“this.b”在原始 MyClass 实例中没有改变?我在这里读到 javascript 没有块范围(只有函数范围)。如果这就是原因,那么为什么不将“this.b”视为“未定义”,将其设置为“现在我 B”?

谢谢!

4

2 回答 2

2

您传递给该方法的匿名回调函数创建了一个新范围,因此当您this.b在回调内部说时,它不再相同b,而是一个新的。

解决它的一种常见方法是this在回调之外创建对要访问的引用:

var self = this;

然后你可以self.b在回调内部引用。

于 2013-04-26T21:26:51.530 回答
2

这是一个很好的开始。

对于您的具体示例,您可以这样编码,保存thisMyClass实例的引用:

MyClass.prototype.changeB = function(callback) {
    var me = this;
    this.a = "now me A";
    doAnotherFunction(function(err, data) {
        me.b = "now me B";
        callback(null, me.b);
    });
};

使用bind响应建议的示例:

MyClass.prototype.changeB = function(callback) {
    this.a = "now me A";
    var fn = function(err, data) {
        this.b = "now me B";
        callback(null, this.b);
    });
    // the first parameter to bind will be the 'this'
    // visible from inside the function
    doAnotherFunction(fn.bind(this));
};

编辑:要找出this您的示例中的内容,请尝试添加一些日志记录:

MyClass.prototype.changeB = function(callback) {
    var me = this;
    this.a = "now me A";
    doAnotherFunction(function(err, data) {
        // Use this['b'] notation to avoid errors using this.b,
        // if this.b doesn't already exist.
        console.log(me, typeof me, this, typeof this, this['b']);
        this.b = "now me B";
        callback(null, this.b);
    });
};
于 2013-04-26T21:28:33.153 回答