node.js / javascript - 嵌套回调

时间:2013-04-26 21:21:13

标签: javascript node.js

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'视为'undefined'而将其设置为“now me B”?

谢谢!

2 个答案:

答案 0 :(得分:2)

您传递给该方法的匿名回调函数会创建一个新范围,因此当您在回调中说this.b时,它不再是b,而是一个新的。{/ p>

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

var self = this;

然后你可以在回调中引用self.b

答案 1 :(得分:2)

Here is a good read开头。

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

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);
    });
};