【问题标题】:Why doesn't typescript use the 'self' trick?为什么打字稿不使用“自我”技巧?
【发布时间】:2014-11-25 08:53:53
【问题描述】:

我编写了以下 TypeScript 代码:

class Person {
    constructor(public firstname: string, public lastname:string){
}

public die(){
    this.lastname += " RIP";
}

这编译为:

var Person = (function() {
    function Person(firstname, lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    Person.prototype.die = function () {
        this.lastname += " RIP";
    };
    return Person;
})();

这当然是一种有效的方式,但在以下情况下它不会按预期工作:

function run(delegate){
    delegate();
}

var person = new Person("guy", "dude");
run(person.die);
alert(person.lastname);
alert(lastname);

此处的预期警报将是“dude RIP”,然后是“undefined”。但是,实际结果将是“dude”和“undefined RIP”。这是因为 this 参数在 JS 中的作用很奇怪。

一个常见的解决方案是通过闭包使用自变量,并放弃原型机制,即

var Person = (function() {
    function Person(firstname, lastname) {
        var self = this;
        self.firstname = firstname;
        self.lastname = lastname;
        self.die = function() {
            self.lastname += " RIP";
        }
    }
    return Person;
})();

这将按预期工作。 这种编译代码的特定方式有什么优势? typescript 是否决定留下那段不直观的代码?

【问题讨论】:

  • 这取决于你,函数的调用者。
  • 放弃原型机制会使代码更加不直观。
  • 你为什么不试试run(person.die.bind(person))?您如何期望 TypeScript 知道当您键入 run(person.die) 时,它应该被编译为 run(person.die.bind(die)) 而不是 run(person.die)?记住,explicit is always better than implicit
  • @Bergi 您可以完全放弃面向对象并选择纯函数式代码。
  • 您还可以修复run 函数以接受上下文参数:function run(delegate, context){ delegate.call(context); },然后是run(person.die, person);

标签: javascript typescript


【解决方案1】:

当你想捕捉它时,你应该使用箭头函数语法。我认为在委托创建而不是类创建时使用它会更好。

唯一需要的改变是:

run(()=>person.die());

这使您可以为任何函数捕获它,而不管它是如何定义的。

【讨论】:

  • 这比公认的更像是黑客的答案要好得多。
【解决方案2】:

您需要稍微更改代码结构以使其使用_this = this 模式:

class Person {
    constructor(public firstName: String, public lastName: String) {
    }

    die = () => {
        this.lastName += "dead"
    }
}

变成:

var Person = (function () {
function Person(firstName, lastName) {
    var _this = this;
    this.firstName = firstName;
    this.lastName = lastName;
    this.die = function () {
        _this.lastName += "dead";
    };
}
return Person;
})();

关键部分是你需要将 die 函数放在对象而不是原型上,这迫使它使用_this = this

【讨论】:

  • 这样我可以决定何时使用该模式,何时不使用。谢谢!我还发现了为什么使用原型比使用这种方法更可取。这样,每个对象都有一个函数的副本,导致更大的内存占用。使用原型,每个对象都变得更苗条。谢谢!
【解决方案3】:

因为这就是 JS 中的类的工作方式。 Typescript 开发人员决定他们不想更改该语言的任何现有功能。

【讨论】:

    猜你喜欢
    • 2016-12-12
    • 2013-02-22
    • 2019-02-18
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 2020-12-12
    • 1970-01-01
    相关资源
    最近更新 更多