在 lambda 中使用关键字 this 与带有 Typescript 的函数时会发生什么

What is happening when using the keyword this in lambdas vs functions with Typescript

本文关键字:函数 Typescript 什么 lambda 关键字 this      更新时间:2023-09-26

我正在为Angular 2项目使用Typescript。我注意到,当我们在 labmda 表达式与函数中使用关键字 this 时,this指的是不同的东西。

例如,假设我有一个如下所示的 Angular 组件。

export class MyComponet {
 isActive = true;
 names = [ "john", "jeff", "jared" ];
 doSomethingWithLambda() {
  names.forEach( (value, index) => {
   if(this.isActive) { //this.isActive refers to MyComponent.isActive
    //do something...
   }
  });
 }
 doSomethingWithFunction() {
  names.forEach( function(value, index) {
   if(this.isActive) { //this.isActive is undefined, since this refers to the function
    //do something
   }
  });
 }
 doSomethingWithFunction2() {
  let isActive = this.isActive;
  names.forEach( function(value, index) {
   if(isActive) { //if we change isActive will this also change MyComponent.isActive?
    //do something
   }
  });
 }
}

这里到底发生了什么(可以这么说是在幕后)?lambda 内部this背后的魔力是什么,使其能够"正确"引用外部类的字段?我知道函数内部this将引用函数本身。

另外,我有一个doSomethingWithFunction2方法,该方法将MyComponent.isActive引用到局部变量中。如果我更改该局部变量,那应该就像更改它引用的变量一样,对吗?(无论是像整数/数字这样的"原语"还是像JSON { }这样的"对象")

fat-arrow函数语法是以下各项的简写:

function () { }.bind(this);

bind是一个Javascript ES5方法,等效于这个:

Function.prototype.bind = function bind(context) {
  var func = this;
  return function () {
    return func.apply(context, arguments);
  };
}

关于

另外,我有一个doSomethingWithFunction2方法,它将MyComponent.isActive引用到局部变量中。如果我更改该局部变量,那应该就像更改它引用的变量一样,对吗?(无论是像整数/数字这样的"原语"还是像JSON { }这样的"对象")

在 Javascript 中,变量就像指针,除了一些有限的情况(原语和写入时复制对象)会在变化时更改引用的值。 重新分配不会更改原始值,例如 isActive = false;this.isActive = false实际上会在this上重新分配变量isActive,现在希望正确分配。

这与 lambda 函数在 TS 中的实现方式有关。 这个 in 箭头函数是按词法推断的,因此它更符合下面的代码

函数 Person() { var self = this;有些人选择that而不是self。 选择一个并保持一致。 自我年龄 = 0;

setInterval(function growUp() { 回调引用其self变量 该值是预期对象。 自我年龄++; }, 1000);}因此,在 lambda 函数中,它实际上不是这个,而是一个上下文更接近自我。这可能不是实际的实现,但更接近于让您了解正在发生的事情。

现在,当您在我无能为力的this之外时,指的是全局变量,这将是window

lambda 函数类似于 javascripts bind 函数。

Protip 查看您的转译 JS 您的 lambda 函数是如何转换的。