【问题标题】:handling "this" to access class fields / methods [duplicate]处理“this”以访问类字段/方法[重复]
【发布时间】:2016-12-27 01:23:00
【问题描述】:

通过查看这段代码,我对在打字稿中使用 this 有点困惑

class GoogleMapsClass {
    public map;

    constructor(selector) {
        var _this = this;
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4) {
                _this.map = this.responseText;
            }
        };
        xhttp.open("GET", "/test.php", false);
        xhttp.send();
    }
}

你可以看到我正在使用上下文切换技巧var _this = this;

我不知道这是否是在 typescript 中处理类字段的正确方法,而且我担心通过使用这个技巧我只是复制了内存,因此它不利于性能和整体代码质量(我知道JS 不是为一些繁重的操作而生的,但在优化代码时,复制对象仍然是最微不足道的错误。

处理上下文切换最正确的方法是什么?

【问题讨论】:

  • 如何复制对象?您正在创建对对象的引用,以便以后可以引用它。不知道你说 JS 不是为一些繁重的操作而生的意思。
  • 您的示例代码 sn-p 在我看来更像是“为什么闭包有用”的示例,而不是“技巧”。如果您正在寻找替代方案,您可以在匿名函数上使用 .bind(this)
  • JS 是一种客户端工具,它不会总是在预期的时间内结束运行,无论如何,你通过提醒我这可以作为传递引用解决了我的问题的一部分,但我我仍然不确定这是否是处理该问题的正确方法。 TS 是否有任何内置的魔法关键字来访问类上下文?
  • TypeScript 只是 javascript。没有新的魔法关键字(字面上改变 javascript 工作方式的词),this 一直存在于 javacsript 中,这就是你可以在 typescript 中使用它的原因。

标签: javascript typescript this


【解决方案1】:

您的代码中没有重复的对象。 _this 只是对this 的引用。事实上,您可以使用箭头函数或绑定您的函数来避免_this

bind:

class GoogleMapsClass {
    public map;

    constructor(selector) {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (xhttp.readyState == 4) {
                this.map = xhttp.responseText;
            }
        }.bind(this);
        xhttp.open("GET", "/test.php", false);
        xhttp.send();
    }
}

Arrow function:

class GoogleMapsClass {
        public map;

        constructor(selector) {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = () => {
                if (xhttp.readyState == 4) {
                    this.map = xhttp.responseText;
                }
            }
            xhttp.open("GET", "/test.php", false);
            xhttp.send();
        }
    }

【讨论】:

  • 这种情况下箭头函数不会失效吗?代码中有两个this。一种是别名为_this 的GoogleMapsClass 对象,一种是对其进行this.readyState 检查的全局对象。
  • @slebetman 不错的收获!我已经编辑了我的答案。谢谢
【解决方案2】:

我在您的代码中看不到任何地方复制对象

$(document).ready(function(){
  
  var first = {};
  var second = first;
  second.value = "whatever";

  $('#test1').text(first.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test1"></div>

在上面的例子中,第一个和第二个指向同一个对象,没有对象的重复。我在第二个上设置了一个值,并且可以从第一个读取它,因为它们实际上是同一个对象。

处理上下文切换最正确的方法是什么?

许多人会执行以下代码行之一:

var _this = this;
var $this = this;
var self = this;

它们都可以工作,并且这样做没有明显的性能或内存问题。

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 2021-07-08
    • 2016-12-12
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    相关资源
    最近更新 更多