【问题标题】:TypeScript: so how exactly is "this" scoped?TypeScript:那么“this”的范围究竟如何?
【发布时间】:2013-02-24 00:06:24
【问题描述】:

我有这段 Typescript 代码:

constructor($triggerHref: JQuery) {
        // stuff...
        var _this = this;
        $(document).on("click",$triggerHref.selector,e=>{
            e.preventDefault();
            var target = $(e.srcElement).attr("data-pcc-sort-trigger");
            if (target == _this.active)
                _this.load(target, !_this.isDescending);
            else _this.load(target, false);
        });

    }

如果我删除 var _this = this; 行并仅在事件处理程序中使用 this,生成的 js 代码看起来相当相同(无论如何它都会生成 _this),但由于某种原因,this.activethis.load() 是未定义。

我对 TS 的作用域的理解是 ()=>{} 方法将 this 与它们的父级保持联系,并且只有 function(){} 方法像通常的 JS 方法一样工作。

那么为什么这个对我不起作用?

【问题讨论】:

  • 你的理解是正确的,当我尝试这个时,生成的代码对我来说是相同的。您发现了哪些差异?
  • @JohnnyHK:在调试器中,this 被解析为包裹在$triggerHref 中的对象,然后代码存在于(target == undefined) 行中而不会引发异常。手动将this 放在那里,一切都按预期工作。
  • @JcFx:这真的重要吗??
  • 你能发布一个更完整的例子吗?
  • @RyanCavanaugh:我稍后会在空闲时间提供一个(带有逐步复制):)

标签: javascript typescript


【解决方案1】:

正如您已经注意到的,lambda 函数在定义 lambda 函数时捕获 this。这可能会导致奇怪的结果(还有一个 few bugsvar _this = this 周围),尽管其中大部分似乎已修复。

整个语言结构似乎是为了欺骗 JavaScript 作用域(this 是调用函数的对象)。

至于你解释的怪异(this.active 和 _this.active 的行为不同),问题范围内没有解释。

生成的 JavaScript(如您所说)应该(几乎)相同。除了编写var _this = this; 导致_this 在同一范围内多次定义并破坏javascript 有效性之外。这是围绕 TypeScript lambda 的问题。永远不要在 TS 中定义_this,因为它是为某些目的而保留的(并且不检查它是否是免费的)。

TypeScript 没有魔法。执行的是它生成的 JavaScript。检查是否有东西覆盖了同一范围内的_this(这很容易发现,因为var _this的范围是构造函数的范围,var也隐藏了来自外部范围的同名变量,所以它应该在构造函数中)。

我暂时避免在 TypeScript 中使用 lambda 表达式。改用简单的匿名函数,不需要您重构任何代码。将this 保存到其他变量可能会被认为是丑陋的,但是您可以通过使用$.proxy() 来解决它。这样,您甚至可以编写一个正则表达式替换来将您的 lambdas 更改为 $.proxy()。暂时。

总而言之,我需要调试生成的 JS 以发现错误,因为您的代码在语法上应该没问题。在我看来,TypeScript 编译器需要围绕这一点重新思考(我希望一些 TS 爱好者会有所不同,并教我如何正确完成它,因为我不反对 TS,相反)。

我很确定@RyanCavanaugh 能够准备一个更好的答案。

【讨论】:

    【解决方案2】:

    lambda 表达式生成一个函数表达式,因此同样的作用域规则适用于作为函数表达式的 lambda 表达式。

    例子:

    var x = e => {};
    

    生成此 Javascript 代码:

    var x = function (e) {
    };
    

    【讨论】:

    • 我想当你在 TypeScript 中使用箭头符号时,它内部的 this 也被限定在你创建它的上下文中。我是否正在考虑一种不同的表示法?
    • @Chad:实际上,我必须收回所有这些。当在对象内使用时,lambda 表达式还会创建一个_this 变量,并且所有对this 的引用都将更改为_this。我不知道为什么这在你的情况下不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 2011-04-29
    • 2015-06-07
    • 2022-01-27
    • 1970-01-01
    相关资源
    最近更新 更多