TypeScript对象字面量中的"this"关键字

8
在对象字面量中的函数中使用this时,它的预期行为是什么?
例如,假设我有一个名为foo的类型,在它上面只有一个名为bar的函数,没有其他属性。但在fooObj.bar方法中,我可以访问this.baz(其中baz不是类型foo上的属性),而且我没有看到任何错误。 TypeScript不应该会出错吗,因为fooObj上没有baz属性?
type foo = {
    bar(): void;
}
var fooObj: foo = {
    bar: () => {
        // TS does not error out when I access this.baz
        console.log(this.baz);
    }
} 

2
你尝试过设置"noImplicitThis":true编译器选项吗? - Aleksey L.
3个回答

7

现在启用此功能的方式是设置编译选项"noImplicitThis": true这个pull request在对象字面量中启用了类型化的this。最初,Aleksey L在一个问题的评论中提出了这个编译器选项,但当时它并没有这样工作。


2
这是实际的解决方案。noImplicitThis 使 this 关键字在对象字面量中按照您的预期工作。 - Andrew Koster

3
你正在使用箭头函数,它具有词法this
不过,在对象字面量中使用非箭头函数属性的简写方式更加简短:
var fooObj: foo = {
    bar() {
        console.log(this.baz);
    }
}

问题仍然存在:baz是什么,为什么TypeScript没有告诉你foo(应该是this的类型)没有baz属性?我对TypeScript并不是非常了解,但整个重点不是你的类型需要明确定义它们的属性吗?我想问题是,为什么在一个词法绑定函数内,this的类型是any,而不是foo的类型? - user229044
1
@meagar: foo 不应该是 this 的类型。this 将是包含对象字面量的函数中的 this - Ry-
啊,是的。我忽略了我们不在ES6类声明中这一事实。那么,为什么TypeScript不查看对象字面声明的上下文,并查看this的任何类型仍然没有baz属性呢? - user229044
@meagar 因为在那段代码中,this 是全局作用域,即 any - Alex
是的,我错过了使用箭头函数的微妙之处。但即使我尝试使用非箭头函数,“this”解析为“any”,而不是foo。这允许访问未在对象文字中定义的属性。 - Arvind Venkataraman

3
这个回答在问题提出时是正确的。但随着typescript和目标javascript版本的更新,情况已经发生了变化。 您让typescript推断thisfooObj
typescript通过创建一个本地变量_this来绑定this,该变量绑定到声明fat-arrow的this-上下文。而在您的情况下,this是全局范围,即any。这就是它编译成的内容:
var _this = this;
var fooObj = {
    bar: function () {
        // TS does not error out when I access this.baz
        console.log(_this.baz);
    }
};

以下是类中的示例:

class Bar
{
    private var = 23;
    public makeSound = () => console.log(this.var) 
}

// Compiles into:

var Bar = (function () {
    function Bar() {
        var _this = this;
        this.var = 23;
        this.makeSound = function () { return console.log(_this.var); };
    }
    return Bar;
}());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接