Angular中typescript的this问题

探讨Angular中TypeScript的this上下文问题,特别是在http请求模块中handleError函数的this指向错误及解决方法,通过箭头函数保持正确的this上下文,避免请求失败时的弹窗通知失效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Angular中typescript的this问题

1. 例子

在使用Angular的时候封装一个http请求模块,具体代码如下:

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { throwError, Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { MsgService } from './confirm.service';


@Injectable({
  providedIn: 'root'
})
export class HttpService {
  constructor(private http: HttpClient, private msgService: MsgService) { }
  /**
   *
   *http错误捕捉
   * @param {HttpErrorResponse} error
   * @returns
   * @memberof HttpService
   */
   handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.log(error.error.message);
      // 发生客户端或者网络错误提醒用户
    } else {
      console.log(this);
      this.msgService.msgError( `请求失败,错误代码为${error.status}`);
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    return throwError(
      'Something bad happened; please try again later.');
  }

  // 也可以统一设置请求头

  // get请求,参数为url,有参数的第二个为请求参数
  httpGet(url: string, myParams?: any): Observable<any> {
    const option = myParams ? { params: new HttpParams({ fromObject: myParams })} : {};
    return this.http.get(url, option).pipe(
      catchError(this.handleError)
    );
  }
  // post请求
  httpPost(url: string, body: any | null, myparams?: any): Observable<any> {
    const options = myparams ? { params: new HttpParams({ fromObject: myparams }) } : {};
    return this.http.post(url, null, options).pipe(
      catchError(this.handleError)
    );
  }
  // 文件上传
}

主要看handleError函数,它是服务类的一个方法,然后在catchError里面作为回调函数,本来我们是希望handleError里的this指代它的对象也就是HttpService,但是结果去让人失望,所以当请求失败的时候就不会出现弹出框,打印出来的this指代的是调用该函数时的上下文。那么如何解决呢,我们知道在es6中的箭头函数能保存函数创建时的 this值,而不是调用时的值,所以我们可以将handleError函数修改。

解决方法

将handleError函数修改成

handleError = (error: HttpErrorResponse) => {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.log(error.error.message);
      // 发生客户端或者网络错误提醒用户
    } else {
      console.log(this);
      this.msgService.msgError( `请求失败,错误代码为${error.status}`);
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    return throwError(
      'Something bad happened; please try again later.');
  }

2. javascript中的this拓展

this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调 用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。

2.1 调用位置

this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调 用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式.

eg:

function baz() {     // 当前调用栈是:baz     // 因此,当前调用位置是全局作用域 
    console.log( "baz" );     bar(); // <-- bar 的调用位置 
} 
function bar() { 
    // 当前调用栈是 baz -> bar     // 因此,当前调用位置在 baz 中 
    console.log( "bar" );     foo(); // <-- foo 的调用位置 
} 
function foo() {     // 当前调用栈是 baz -> bar -> foo     // 因此,当前调用位置在 bar 中 
    console.log( "foo" );
} 
baz(); // <-- baz 的调用位置
2.2 绑定规则
2.1 默认绑定

在严格模式下绑定到 undefined,否则绑定到全局对象当this不符合其他绑定规则时默认就是window,比如说

function foo() { 
    console.log( this.a ); 
}
var a = 2;
foo(); // 最后结果就是2,this则指代的是window
 
2.2 隐式绑定

函数引 用有上下文对象时,隐式绑定规则会把函数调用中的 this 绑定到这个上下文对象,比如说:

function foo() { 
  console.log( this.a ); 
} 
 
var obj2 = { a: 42, foo: foo }; 
 
var obj1 = { a: 2, obj2: obj2  }; 
 
obj1.obj2.foo(); // 42
2.3 显示绑定

显示绑定主要是使用call,apply显示的绑定this的指向,它们的第一个参数是一个对象,它们会把这个对象绑定到 this,接着在调用函数时指定这个 this。因为你可以直接指定 this 的绑定对象,因此我 们称之为显式绑定。
eg:

function foo() { console.log( this.a ); } 
 
var obj = { a:2 }; 
 
foo.call( obj ); // 2

另外哈有bind也可以硬绑定this:

function foo(something) { 
  console.log( this.a, something);
  return this.a + something;
} 
var obj = { a:2 }; 
var bar = foo.bind( obj ); 
var b = bar( 3 ); // 2 3 
console.log( b ); // 5

2.4 new绑定

使用 new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。

  1. 创建(或者说构造)一个全新的对象。
  2. 这个新对象会被执行 [[ 原型 ]] 连接。
  3. 这个新对象会绑定到函数调用的 this
  4. 如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。
function foo(a) { this.a = a; }  
var bar = new foo(2);
console.log(bar.a); // 2

使用 new 来调用 foo(…) 时,我们会构造一个新对象并把它绑定到 foo(…) 调用中的 this 上。new 是最后一种可以影响函数调用时 this 绑定行为的方法,我们称之为 new 绑定.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值