JavaScriptの中のthis(FCC成都全スタック大会賀老【this in js】テーマ記録)
7355 ワード
前言
成都FCC全スタック大会のお祝い「This In JS」のテーマ記録を共有しています.Javascriptの中でthisと他の言語のthisは違っています.私たちは環境や文法、呼び方などによって、いつも様々な奇妙な方向を指しているかもしれません.
本文
例を見に来ました.
・・・・・
答えは印刷
このように見ると問題は大きくないようです.問題はすぐに位置づけられるので、コードをこう変えます.
PromiseReject caled on non-object
なぜですか?
thisの問題
習っても問題があるかもしれません.具体的には:穴を掘ることができます. は、 を隠すことができます.位置決めが難しい ES 6ソリューション
JSでは、thisを使っているところは主にあります.一般関数 コールバック関数 コンストラクタ メソッド
ES 6において、私たちは
Outdated draft:gilbert/es-explicit-this
thisを表示
関数では、thisは実は隠蔽変数として開発者に提供されていることを知っています.
例1
例2
例3
Outdated draft:hax/proposal-functionn-this
具体的な属性を追加しました.
締め括りをつける
上の紹介は今は提案だけで、実際に支持していません.合格するかどうかは分かりません.しかし紹介から見て、確かにthisの問題を解決しました.第三者倉庫とフレームを開発した学生にとってはいいニュースです.普通の開発者にとっても、間接的に開発体験を高めることができます.
ここで述べた提案の住所
Outdated draft:gilbert/es-explicit-this Outdated draft:hax/proposal-function-this
成都FCC全スタック大会のお祝い「This In JS」のテーマ記録を共有しています.Javascriptの中でthisと他の言語のthisは違っています.私たちは環境や文法、呼び方などによって、いつも様々な奇妙な方向を指しているかもしれません.
本文
function f() { this }
function f() { 'use strict'; this }
const f = () => this
まずこのような簡単な例を見てみます.この例はみんなJSや面接の時に使ったことがあると信じています.私たちは違った文法環境の下で、異なったモードの下で、thisは違う値かもしれません.同時に、this
の取得値もコードコール方式に依存している.f()
obj.f()
new f()
関数コールですか?オブジェクトの属性呼び出し?またはコンストラクタの形式で呼び出しますか?同時にJSは、私たちがよく使うcall apply bind
のように、thisの指向を変える独特の方法もあります.f.call(obj)
f.call(null)
f.call(42)
f.call()
もしcallからnullが入ってきたら、一つの数字が入ってくるとは思わなかったかもしれません.this
は何であるかと同時に、これらは上記のように厳格なモードであるかどうかと関係があり、異なるモードでもthis
は変化します.例を見に来ました.
class Greeting {
static from(control) { return new Greeting(control.value) }
constructor(name) { this.name = name }
hello() { console.log(`Hello ${this.name || 'world'}!`) }
}
[...myForm.elements]
.map(e => [e, Greeting.from(e)])
.forEach(([e, {hello}]) => e.addEventListener('click', hello))
このようなコードは、
をクリックすると、どのような言葉が印刷されますか?・・・・・
答えは印刷
Hello chengdu
で、clickを呼び出すと、thisは実はelementを指しています.つまり、最後に印刷されたnameは実は元素上のname
属性です.このように見ると問題は大きくないようです.問題はすぐに位置づけられるので、コードをこう変えます.
class Greeting {
static from(control) { return new Greeting(control.value) }
constructor(name) { this.name = name }
hello() { console.log(`Hello ${this.name || 'world'}!`) }
}
[...myForm.elements]
.map(e => [e, Greeting.from(e)])
.forEach(([e, {hello}]) => e.addEventListener('click', hello))
私達の実行ロジックはinput
上のvalue
をプリントしたいです.プリントアウトしたら、間違いなくHello chengdu
をプリントしました.実はこのコードは上記と比べてBugがあります.今度メンテナンスしたら、バグが出ても位置決めが難しいです.Promise
の中のthisを見に来ました.Promise.all(numberPromises)
.then(values => {
const nonNumbers = values.filter(isNaN)
return Promise.all(values.concat(nonNumbers.map(Promise.reject)))
})
.then(nextStep)
.catch(errorLogger)
これは文章が変なコードです.つまり、数字ではない値を選別して、組織でないものがあれば、catchに入れ、errorを呼び出します.error Loggarで情報を印刷する時、私達は数字ではない値を印刷したいと思いますが、実際にcatchに行ったら、印刷したのはPromiseReject caled on non-object
なぜですか?
Promise.reject
は静的な関数だと思いますが、標準Promiseの定義にはthisが必要です.Promiseの定義には布団類化が可能です.Promise.reject
を呼び出したら、彼は現在のthisが指している種類を見ます.Promiseサブクラスであれば、Promiseサブクラスのインスタンスを作成します.ほとんどの人にとっては、Promise.reject
にthisが必要かどうかはよく分かりませんよね.thisの問題
習っても問題があるかもしれません.具体的には:
JSでは、thisを使っているところは主にあります.
ES 6において、私たちは
class
を提供して、コンストラクタthisの問題を解決し、allow function
を提供して解決しました.実は私たちはthisの判断に失敗する可能性がある場合、
および
がまだあります.普通の状況では、私たち自身のコードはまだthis
を指していますが、第三者ライブラリとフレームワークについては、何を指しているのか分かりにくいです.賀さんは次のT 39会議で提出します.言語レベルでthisの曖昧さを解決します.Outdated draft:gilbert/es-explicit-this
thisを表示
関数では、thisは実は隠蔽変数として開発者に提供されていることを知っています.
this
を表示してもいいですか?TSでは、このようなコードが使えます.Number.prototype.toHex = function (this: number) {
return this.toString(16)
}
表示されたthisはnumberタイプのコードであり、thisを示す方式を参考にして、次のようなコードを構築することができます.function getX(this) { // this
return this.x
}
function getX(this o) { //
return o.x
}
function getX(this {x}) { //
return x
}
このように書くと、何かメリットがありますか?例1
// original code
class Player {
attack(opponent) {
return Game.calculateResult(
this.input(),
opponent.input(),
)
}
}
// better naming
class Player {
attack(this offense, defense) {
return Game.calculateResult(
offense.input(),
defense.input(),
)
}
}
別名を通してコードの可読性を高めることができます.例2
// original code
function process (name) {
this.taskName = name;
const that = this
doAsync(function (amount) {
this.x += amount;
that.emit('change', this)
});
};
// better naming
function process (this obj, name) {
obj.taskName = name;
doAsync(function callback (this result, amount) {
result.amount += 2;
obj.emit('change', result)
});
};
私たちは、同じ名前の変数は前者をカバーし、thisも例外ではないことを知っています.この例はthis
の方法で、 this
が欲しいものであることを保証します.別の変数を定義しなくてもいいです.例3
function div(@int32 this numerator, @int32 denominator) {
// if (numerator !== numerator|0) throw new TypeError()
// if (denominator !== denominator|0) throw new TypeError()
// ...
}
表示されたthisを使用した後、いくつかの共通論理処理thisをthis
でカプセル化することもできます.この提案は主にdecorator
が紛らわしい問題を指摘して解決しました.ここで、賀さんはミスを指摘している問題を早期発見するために、別の提案を出しました.Outdated draft:hax/proposal-functionn-this
具体的な属性を追加しました.
this
を使用して、この属性を使用して、予め私たちがミスをしたかどうかを発見しました.例えば、API thisArgumentExpected
を定義します.// safer API:
function on(eventTarget, eventType, listener, options) {
if (listener.thisArgumentExpected) throw new TypeError('listener should not expect this argument')
return eventTarget.addEventListener(eventType, listener, options)
}
このアプリがon
がtrueであることを発見したら、事前にエラーを投げて、クリックを待つ必要がない時にエラーを発見します.早ければ早いほど、コードの安定性がよくなります.また、場合によってはthisArgumentExpected
、thisArgumentExpected
も自動的に変化します.//
let arrow = () => { this }
arrow.thisArgumentExpected // false
// bind
let bound = f1.bind()
bound.thisArgumentExpected // false
// bind
function func() {}
func.thisArgumentExpected // false
// bind
function implicitThis() { this }
implicitThis.thisArgumentExpected // true
// this
function explicitThis(this) {}
explicitThis.thisArgumentExpected // true
//
class C {
m1() {}
m2() { this }
m3(this) {}
m4() { super.foo }
static m1() {}
static m2() { this }
static m3(this) {}
static m4() { super.foo }
}
C.prototype.m1.thisArgumentExpected // false
C.prototype.m2.thisArgumentExpected // true
C.prototype.m3.thisArgumentExpected // true
C.prototype.m4.thisArgumentExpected // true
C.m1.thisArgumentExpected // false
C.m2.thisArgumentExpected // true
C.m3.thisArgumentExpected // true
C.m4.thisArgumentExpected // true
C.thisArgumentExpected // null
このような形式によって、対応するAPIの増加thisArgumentExpected
を検出すると、私たちのコードがthisArgumentExpected
でエラーを指す可能性があるかどうかを事前に知ることができる.締め括りをつける
上の紹介は今は提案だけで、実際に支持していません.合格するかどうかは分かりません.しかし紹介から見て、確かにthisの問題を解決しました.第三者倉庫とフレームを開発した学生にとってはいいニュースです.普通の開発者にとっても、間接的に開発体験を高めることができます.
ここで述べた提案の住所
Outdated draft:gilbert/es-explicit-this Outdated draft:hax/proposal-function-this