当函数作为参数传递给链时,“this”未定义

时间:2015-11-05 10:56:41

标签: javascript ecmascript-6 babeljs

我的问题的简单例子

考虑以下情况,我在a的承诺链中使用了一些函数(bc):

class SomeClass {
    constructor(){
        this.v1 = 1;
        this.v2 = 2;
    }

    a() {
        return new Promise((resolve, reject) => {
            console.log('a', this.v1);  // Do something with `this`
            resolve();
        });
    }

    b() {
        return new Promise((resolve, reject) => {
            console.log('b', this.v2);   // Do something with `this`
            resolve();
        });
    }

    c() {
        return this.a().then(this.b);   // passing b as argument
    }
}

当我致电c并运行承诺链时,this中的b未定义。

const sc = new SomeClass();

sc.c().then(() =>{
    console.log('done')
}).catch((error) => {
    console.log('error', error);
});

输出:

a 1
error [TypeError: Cannot read property 'v2' of undefined]

我知道箭头函数继承了外部this,但我不确定为什么它是未定义的,因为我从c调用它。

2 个答案:

答案 0 :(得分:2)

问题在于:

this.a().then(this.b)

因为this.b检索到的结果函数已从this解除绑定(您实际上并未按照问题中所述的方式调用它)。

您可以通过使用箭头方法保留范围,以与代码的其余部分一致的方式解决此问题:

this.a().then(obj => this.b(obj))

或者您可以使用.bind来获得类似的结果:

this.a().then(this.b.bind(this))

答案 1 :(得分:-1)

我对ES6不太熟悉,但我认为当你在.then()中调用一个函数时,该函数中的this将引用其他东西,特别是在这种情况下,{{从.then()调用的b()中的1}}将引用之前调用a()返回的实际Promise。

解决方法是将当前对象作为b()的参数传递,并使用它来访问v2。不确定它是否适合您的需要。

所以代码就像这样:

this

示例http://www.es6fiddle.net/igm5w99s/