先前一直以为函数调用没有设置调用对象都是指向全局对象,但是最近发现匿名函数的this有些奇特,没有实例很难说的清楚。先举一个graphql-module案例的一段代码

import { Injectable, ProviderScope } from '@graphql-modules/di';
import { resolve } from 'path';
import axios from 'axios';
import { trackProvider } from '@safe-api/middleware';
import { RandomPhoto } from '../../types/unsplash';

interface RandomPhotoInput {
  query: string;
  orientation: 'landscape' | 'portrait' | 'squarish';
}

@Injectable({
  scope: ProviderScope.Application,
})
export class UnsplashApi {
  baseURL = 'https://api.unsplash.com/';

  async getRandomPhoto() {
    const trackedRandomPhoto = await trackProvider(
      async ({ query, orientation }: RandomPhotoInput) => {
        const response = await axios.get<RandomPhoto>('photos/random', {
          baseURL: this.baseURL,
          headers: {
            Authorization:
              'Client-ID 4d048cfb4383b407eff92e4a2a5ec36c0a866be85e64caafa588c110efad350d',
          },
          params: {
            query,
            orientation,
          },
        });

        return response.data;
      },
      {
        provider: 'Unsplash',
        method: 'RandomPhoto',
        location: resolve(__dirname, '../logs/main'),
      }
    );

    try {
      return (await trackedRandomPhoto({
        query: 'portrait',
        orientation: 'squarish',
      })).urls.small;
    } catch (err) {
      console.error('Cannot retrieve random photo:', err);
      return null;
    }
  }
}

执行UnsplashApi类实例方法getRandomPhoto 会执行await trackProvider(callback),callback是一个箭头函数,方法体里有
baseURL: this.baseURL 这里的this是指向UnsplashApi实例的。如果callback不是箭头函数则this指向全局

接着是我自己设计的该现象在proxy中的应用一个报警器

class A {
    showWaringMessage(property){
            console.log(`${property} is not exit`)
        }
    createProxy() {
        
        let handeler = {}
        handeler.get=(target, property, receiver) =>{
                        //console.log(this)
                       let result = Reflect.get(target, property, receiver)
                       if(!result){
                           this.showWaringMessage(property)
                       };
                       return result
                    }
        
        const proxy = new Proxy({},handeler
       
        );
        return proxy
    }
}


let aDemo = new A()
aDemo.createProxy().a

这里的this指向class A实例。
根据“该函数所在的作用域指向的对象”来分析一下:
该函数所在的作用域:箭头函数handeler.get 所在的作用域是createProxy,因为createProxy是一个函数。作用域指向的对象:aDemo.createProxy指向的对象是aDemo.createProxy。


lyh1091106900
1 声望0 粉丝