JavaScript Thisの六つのカン

4131 ワード

thisスタイルの操作方法を考えると、thisに対する理解はいつまでも古い話題であり、本稿では、この磨人の妖精を六つの塊から大きく外すことによって釘付けにしようとする.
まずは
this is all about context.
thisははっきり言って、大家を探して、現在の文脈を持つ対象を探します.
大きい人は六階に分けられます.階数が高いほど権力が大きくなります.
世界の果て
権力の最小のオーディエンスは子持ちとしての存在で、普通は全体の局面で、ブラウザーの中でwindowです.use strictの場合はundefinedです.
function showThis () {
  console.log(this)
}
function showStrictThis () {
  'use strict'
  console.log(this)
}
showThis() // window
showStrictThis() // undefined

補足説明:関数が匿名関数である場合、その指向もwindowです.
第二階:石を注文して金になる
二階のオーディエンスはこの関数の前のポイントを探しています.
thisを使うその関数があるcontext objectに属しているなら、このcontext objectはthisに結び付けられます.
例えば、次の例では、bossはreturnThisのcontext objectであり、あるいはreturnThisはbossに属します.
var boss = {
  name: 'boss',
  returnThis () {
    return this
  }
}
boss.returnThis() === boss // true
次の例は気をつけてください.答えが出ますか?
var boss1 = {
  name: 'boss1',
  returnThis () {
    return this
  }
}
var boss2 = {
  name: 'boss2',
  returnThis () {
    return boss1.returnThis()
  }
}
var boss3 = {
  name: 'boss3',
  returnThis () {
    var returnThis = boss1.returnThis
    return returnThis()
  }
}
boss1.returnThis() // boss1
boss2.returnThis() // ?
boss3.returnThis() // ?
答えはboss 1とwindowですよ.正しいですか?
thisを使っているその関数を見てください.
boss 2.returnThisの中で、thisの関数を使うのはboss 1.returnThisで、だからthisはboss 1に結び付けます.
boss 3.returnThisでは、thisの関数を使ってreturnThisですので、予備のタイヤにthisをバインドします.
thisをboss 2に結び付けるにはどうすればいいですか?

var boss1 = {
  name: 'boss1',
  returnThis () {
    return this
  }
}
var boss2 = {
  name: 'boss2',
  returnThis: boss1.returnThis
}
boss2.returnThis() //boss2

//            ,         ,           ,      return something ,             

//      boss2.returnThis()     return boss1.returnThis(),    this boss1
第三層:腹を指して結婚する
3階のオーディエンスはObject.prototype.callとObject.prototype.applyで、パラメータでthisを指定できます.(thisは直接に値を付けてはいけません.this=2はReferenceErrに報告します.)
function returnThis () {
  return this
}
var boss1 = { name: 'boss1' }
returnThis() // window
returnThis.call(boss1) // boss1
returnThis.apply(boss1) // boss1
第四層:誓いの山
第四階のオーディエンスはObject.prototype.bindで、彼は新しい関数を通じて永久的な結合を提供するだけでなく、第三層オーディエンスの命令をカバーします.
function returnThis () {
  return this
}
var boss1 = { name: 'boss1'}
var boss1returnThis = returnThis.bind(boss1)
boss1returnThis() // boss1
var boss2 = { name: 'boss2' }
boss1returnThis.call(boss2) // still boss1
第五階:内に乾坤がいます.
無視しやすいのが、thisを結びつけるところがnewです.new関数があると、自動的に新しいオブジェクトにthisを結びつけて、この関数を呼び出します.これはビッドのバインディングをカバーします.
function showThis () {
  console.log(this)
}
showThis() // window
new showThis() // showThis
var boss1 = { name: 'boss1' }
showThis.call(boss1) // boss1
new showThis.call(boss1) // TypeError
var boss1showThis = showThis.bind(boss1)
boss1showThis() // boss1
new boss1showThis() // showThis
第六階:軍令は山のようです.
最後の無法無尽のオーディエンスはES 2015の矢印関数です.矢印関数のthisは妖艶ではなく、現在の語法のスコープに永遠に封印されています.これはLexical thisといいます.コードが実行される前に確認できます.他の大きな人はカバーできません.
このような利点は、反転関数のthisが現在の作用領域を使用して、混淆を起こさないようにすることです.
矢印関数は、どこで作られたかを見るだけでいいです.
function callback (cb) {
  cb()
}
callback(() => { console.log(this) }) // window
var boss1 = {
  name: 'boss1',
  callback: callback,
  callback2 () {
    callback(() => { console.log(this) })
  }
}
boss1.callback(() => { console.log(this) }) // still window
boss1.callback2(() => { console.log(this) }) // boss1
以下のような奇抜な使い方には注意が必要です.
var returnThis = () => this
returnThis() // window
new returnThis() // TypeError
var boss1 = {
  name: 'boss1',
  returnThis () {
    var func = () => this
    return func()
  }
}
returnThis.call(boss1) // still window
var boss1returnThis = returnThis.bind(boss1)
boss1returnThis() // still window
boss1.returnThis() // boss1
var boss2 = {
  name: 'boss2',
  returnThis: boss1.returnThis
}
boss2.returnThis() // boss2
最後になぜboss 2なのか分からない場合は、「矢印関数については、どこで作成されているかを見てください」という言葉を理解し続けます.