2014-11-25 22 views
3

我寫了下面的打字稿代碼:爲什麼不打字使用'自我'的伎倆?

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」。但是,實際結果將是「夥計」和「未定義的RIP」。這是因爲這個參數在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; 
})(); 

如預期這將工作。 編譯代碼的具體方法的優點是什麼?打字稿是否決定留下那些不直觀的代碼?

+2

這是由您決定的函數的調用者。 – elclanrs 2014-11-25 08:55:38

+0

放棄原型機制會導致更直觀的代碼。 – Bergi 2014-11-25 08:59:26

+0

你爲什麼不試試'run(person.die.bind(person))'?你如何期望TypeScript知道,當你鍵入'run(person.die)'時,它意味着被編譯爲'run(person.die.bind(die))'而不是'run(person.die)' ?請記住,[顯式總是比隱式更好](http://legacy.python.org/dev/peps/pep-0020/)。 – 2014-11-25 08:59:41

回答

7

你需要改變你的代碼的結構稍微得到它使用_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; 
})(); 

的關鍵部分是,你需要將模具功能上的對象不是原型,這迫使它使用_this = this

+5

這樣我就可以決定何時使用這種模式,什麼時候不使用。謝謝! 我也發現爲什麼使用原型比使用這種方法更可取。通過這種方式,每個對象都擁有該函數的副本,從而導致更大的內存佔用。使用原型,每個對象都很苗條。謝謝! – Gilthans 2014-11-25 11:24:10

3

當你想捕獲這個時,你應該使用箭頭函數語法。我認爲在代理創建而不是創建類的時候使用它會更好。

是唯一需要的變化:

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

這可以讓你捕捉這對任何功能,無論它是如何定義的。

+0

這是比接受的答案更好的方式,更多的是黑客。 – 2016-08-29 11:31:03

相關問題