在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ TypeScript里的this
初始化項(xiàng)目結(jié)構(gòu)
聯(lián)合類型
介紹
介紹
介紹
編譯選項(xiàng)
TypeScript 1.6
介紹
介紹
發(fā)展路線圖
介紹
在MSBuild里使用編譯選項(xiàng)
可迭代性
TypeScript 1.3
介紹
介紹
TypeScript 1.1
變量聲明
即將到來的Angular 2框架是使用TypeScript開發(fā)的。 因此Angular和TypeScript一起使用非常簡(jiǎn)單方便
tsconfig.json
介紹
介紹
介紹
在MSBuild里使用編譯選項(xiàng)
使用TypeScript的每日構(gòu)建版本
新建工程
枚舉
三斜線指令
結(jié)合ASP.NET v5使用TypeScript
TypeScript里的this
介紹
TypeScript 1.4
編碼規(guī)范
介紹
模塊解析
ASP.NET 4
架構(gòu)概述
介紹
介紹
ASP.NET Core
TypeScript 1.8
介紹
介紹
創(chuàng)建簡(jiǎn)單工程
TypeScript 1.7
TypeScript 1.5
NPM包的類型
支持TypeScript的編輯器

TypeScript里的this

介紹

在JavaScript里(還有TypeScript),this關(guān)鍵字的行為與其它語言相比大為不同。這可能會(huì)很令人吃驚,特別是對(duì)于那些使用其它語言的用戶,他們憑借其直覺來想象this關(guān)鍵字的行為。

這篇文章會(huì)教你怎么識(shí)別及調(diào)試TypeScript里的this問題,并且提供了一些解決方案和各自的利弊。

典型癥狀和危險(xiǎn)系數(shù)

丟失this上下文的典型癥狀包括:

  • 類的某字段(this.foo)為undefined,但其它值沒有問題
  • this的值指向全局的window對(duì)象而不是類實(shí)例對(duì)象(在非嚴(yán)格模式下)
  • this的值為undefined而不是類實(shí)例對(duì)象(嚴(yán)格模式下)
  • 調(diào)用類方法(this.doBa())失敗,錯(cuò)誤信息如“TypeError: undefined is not a function”,“Object doesn't support property or method 'doBar'”或“this.doBar is not a function”

程序中應(yīng)該出現(xiàn)了以下代碼:

  • 事件監(jiān)聽,比如window.addEventListener('click', myClass.doThing);
  • Promise解決,比如myPromise.then(myClass.theNextThing);
  • 第三方庫回調(diào),比如$(document).ready(myClass.start);
  • 函數(shù)回調(diào),比如someArray.map(myClass.convert)
  • ViewModel類型的庫里的類,比如<div data-bind="click: myClass.doSomething">
  • 可選包里的函數(shù),比如$.ajax(url, { success: myClass.handleData })

JavaScript里的this究竟是什么?

已經(jīng)有大量的文章講述了JavaScript里this關(guān)鍵字的危險(xiǎn)性。查看這里,這里,或這里。

當(dāng)JavaScript里的一個(gè)函數(shù)被調(diào)用時(shí),你可以按照下面的順序來推斷出this指向的是什么(這些規(guī)則是按優(yōu)先級(jí)順序排列的):

  • 如果這個(gè)函數(shù)是function#bind調(diào)用的結(jié)果,那么this指向的是傳入bind的參數(shù)
  • 如果函數(shù)是以foo.func()形式調(diào)用的,那么this值為foo
  • 如果是在嚴(yán)格模式下,this將為undefined
  • 否則,this將是全局對(duì)象(瀏覽器環(huán)境里為window

這些規(guī)則會(huì)產(chǎn)生與直覺相反的效果。比如:

class Foo {
  x = 3;
  print() {
    console.log('x is ' + this.x);
  }
}

var f = new Foo();
f.print(); // Prints 'x is 3' as expected

// Use the class method in an object literal
var z = { x: 10, p: f.print };
z.p(); // Prints 'x is 10'

var p = z.p;
p(); // Prints 'x is undefined'

this的危險(xiǎn)信號(hào)

你要注意的最大的危險(xiǎn)信號(hào)是在要使用類的方法時(shí)沒有立即調(diào)用它。任何時(shí)候你看到類方法被引用了卻沒有使用相同的表達(dá)式來調(diào)用時(shí),this可能已經(jīng)不對(duì)了。

例子:

var x = new MyObject();
x.printThing(); // SAFE, method is invoked where it is referenced

var y = x.printThing; // DANGER, invoking 'y()' may not have correct 'this'

window.addEventListener('click', x.printThing, 10); // DANGER, method is not invoked where it is referenced

window.addEventListener('click', () => x.printThing(), 10); // SAFE, method is invoked in the same expression

修復(fù)

可以通過一些方法來保持this的上下文。

使用實(shí)例函數(shù)

代替TypeScript里默認(rèn)的原型方法,你可以使用一個(gè)實(shí)例箭頭函數(shù)來定義類成員:

class MyClass {
    private status = "blah";

    public run = () => { // <-- note syntax here
        alert(this.status);
    }
}
var x = new MyClass();
$(document).ready(x.run); // SAFE, 'run' will always have correct 'this'
  • 好與壞:這會(huì)為每個(gè)類實(shí)例的每個(gè)方法創(chuàng)建額外的閉包。如果這個(gè)方法通常是正常調(diào)用的,那么這么做有點(diǎn)過了。然而,它經(jīng)常會(huì)在回調(diào)函數(shù)里調(diào)用,讓類實(shí)例捕獲到this上下文會(huì)比在每次調(diào)用時(shí)都創(chuàng)建一個(gè)閉包來得更有效率一些。
  • 好:其它外部使用者不可能忘記處理this上下文
  • 好:在TypeScript里是類型安全的
  • 好:如果函數(shù)帶參數(shù)不需要額外的工作
  • 壞:派生類不能通過使用super調(diào)用基類方法
  • 壞:在類與用戶之前產(chǎn)生了額外的非類型安全的約束:明確了哪些方法提前綁定了以及哪些沒有

本地的胖箭頭

在TypeScrip里(這里為了講解添加了一些參數(shù)) :

var x = new SomeClass();
someCallback((n, m) => x.doSomething(n, m));
  • 好與壞:內(nèi)存/效能上的利弊與實(shí)例函數(shù)相比正相反
  • 好:在TypeScript,100%的類型安全
  • 好:在ECMAScript 3里同樣生效
  • 好:你只需要輸入一次實(shí)例名
  • 壞:你要輸出2次參數(shù)名
  • 壞:對(duì)于可變參數(shù)不起作用('rest')

Function.bind

var x = new SomeClass();
// SAFE: Functions created from function.bind are always preserve 'this'
window.setTimeout(x.someMethod.bind(x), 100);
  • 好與壞:內(nèi)存/效能上的利弊與實(shí)例函數(shù)相比正相反
  • 好:如果函數(shù)帶參數(shù)不需要額外的工作
  • 壞:目前在TypeScript里,不是類型安全的
  • 壞:只在ECMAScript 5里生效
  • 壞:你要輸入2次實(shí)例名
上一篇:TypeScript 1.4下一篇:NPM包的類型