TypeScript 范围的“this”问题

TypeScript "this" issue with scope

提问人:AnonBNR 提问时间:6/9/2021 更新时间:6/9/2021 访问量:161

问:

我的代码片段:

class MyClass {
    name = "MyClass";

    // traditional method definition
    getName1(){
        return this.name;
    }

    // method defined as an arrow function
    getName2 = () => {
        return this.name;
    }

    // traditional method definition using a this parameter
    getName3(this: MyClass){
        return this.name;
    }
}

const c = new MyClass();
const obj = {
    name: "obj",
    getName1: c.getName1,
    getName2: c.getName2,
    getName3: c.getName3
};

const g = c.getName3;

console.log(c.getName1());
// "MyClass" because this is called in the context of c
// using a traditional method definition getName1

console.log(c.getName2());
// "MyClass" because this is called in the context of c
// using an arrow function getName2

console.log(c.getName3());
// "MyClass" because this is called in the context of c
// using a traditional method definition getName3, having
// a this parameter that statically enforce the context of c

console.log(obj.getName1()); 
// "obj" because this is called in the context of obj
// using the MyClass traditional method definition getName1()
// and assigning it to obj's getName1 property

console.log(obj.getName2()); 
// "MyClass" because this is called in the context of obj
// using an arrow function getName2 and assigning it 
// to obj's getName2 property, but which will preserve c's context
// nonetheless

console.log(obj.getName3()); 
// "obj" but why? Isn't the context of this enforced as that of MyClass? Shouldn't I get
// « The 'this' context of type 'obj' is not assignable to method's 'this' of type 'MyClass' »

console.log(g()); 
// Error, the 'this' context of type 'void' is not assignable to method's 'this' of type 'MyClass'.
// but isn't g declared in the global this context?

我的问题在评论中突出显示,但我仍将将它们列出如下:

  1. 为什么显示?强制执行的上下文不是 的上下文吗?我不应该得到类似的东西吗?console.log(obj.getName3());"obj"thisMyClass

类型为“obj”的“this”上下文不能分配给方法的“this” 类型为“MyClass”

  1. 我知道它不是在对象/类的上下文中声明的,但它不是在全局对象上下文中声明的,因此应该引用?如果是这样,那么为什么我会得到以下内容:gthisglobalThis

类型为“void”的“this”上下文不可分配给方法的“this” 类型为“MyClass”。

TypeScript 作用域

评论


答:

1赞 thecOdemOnkey 6/9/2021 #1

我认为打字稿将“外部”对象推断为这样,因此您可以从 obj.getName3() 获得“obj”,这没关系,因为它也与类匹配。它有名称 attr 和所有方法,所以没关系。

如果将 obj.name 更改为 obj.noname(或 fn 名称之一),则无法调用 obj.getName3(),因为这样 obj 将不再与类匹配。

g() 也是如此。g 的外部对象是 void,没有 name 属性(和 fns),因此您会收到其他错误消息。

阅读更多:https://www.typescriptlang.org/docs/handbook/2/functions.html#declaring-this-in-a-function