Promise中this指向问题

Promisethis指向问题

1、this指向window还是实例?

下面分析两段JavaScript代码段,共用下面这段Html代码:

<div id="app">
    <input type="button" value="获取笑话" @click="getJoke">
    <p> {
    { joke }}p>
div>

this指向window

// 引入axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
// 引入vue
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
var app = new Vue({
     
    el:"#app",
    data:{
     
        joke:"很好笑的笑话"
    },
    methods: {
     
        getJoke() {
     
            console.log( axios.get("https://autumnfish.cn/api/joke") ); // Promise {} 对象
            axios.get("https://autumnfish.cn/api/joke").then( function (response) {
     
                console.log(this); // promise的then中回调函数为匿名函数时,this会指向 window
            },function (err) {
     
                console.log(err);
            }) 
        }
    }
})

this指向实例:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
var app = new Vue({
     
    el:"#app",
    data:{
     
        joke:"很好笑的笑话"
    },
    methods: {
     
        getJoke() {
     
            axios.get("https://autumnfish.cn/api/joke").then( response => {
     
                console.log(this); // promise的then中回调函数为箭头函数时,this指向外层第一个普通函数的this,本例中指向Vue实例
            },function (err) {
     
                console.log(err);
            }) 
        }
    }
})

通过对比这两段JavaScript代码才明白this指向的具体场景。

总结:

Promise对象的回调函数是匿名函数时,this指向window,需要对回调函数bind(this)来改变其this指向。

Promise对象的回调函数是箭头函数时,this指向外层第一个普通函数的this。本例中指向Vue实例。

所以还是箭头函数在this指向方面比较好用。

2、this指向undefined还是实例?

这次用一个类来说明this指向:

// 类
class Dog {
       
    constructor() {
         
        this.name = 'a dog'; 
    }
    start() {
         
        console.log( this.p() ); // Promise {: 'good'}
        this.p().then( () => {
     console.log(this)}); // Dog {name: "a dog"}
        this.p().then( function (res) {
     console.log(this)}); // 打印undefined 
    }
    p() {
         
        return new Promise( (resolve, reject) => {
      // 箭头函数
            console.log(this); // this指向外层第一个普通函数的this 本例中是Dog类对象Dog {name: "a dog"}
            resolve('good'); // 成功返回good
        })
    }
}
let dog = new Dog();
dog.start();

看一下打印结果:

Promise中this指向问题_第1张图片
在这个例子中可以得到结论:

Promise对象的回调函数是匿名函数时,this指向undefined

Promise对象的回调函数是箭头函数时,this指向外层第一个普通函数的this。本例中指向类Class的实例。

3、this指向undefined还是window

继前两个例子,可以看出Promise对象的回调函数如果是箭头函数时,this指向一致,都是指向外层第一个普通函数的this。但是Promise对象的回调函数如果是匿名函数时,两个例子中的this指向是不一样的!

很奇怪?为什么第二个例子Promise对象的回调函数是匿名函数时打印undefined

仔细看,可以注意到在第二个例子中,p()函数返回了一个成功的Promise对象,(Promise {: 'good'})。而在第一个例子中,使用axios请求测试接口地址时返回的Promise对象状态是PendingPromise {})。

总结:

Promise对象的状态是pending,那么匿名回调函数的this指向window

Promise对象的状态是resolved,那么匿名回调函数的this指向undefined

好的,记录了一下难缠的this指向问题,到这里总结完毕。

你可能感兴趣的:(javascript)