jsの中でthisが指す問題について


この文章はコードの実行によって、thisの具体的な方向を説明します.
標準バインディング
シーン1:
console.log('    ', this) // window
普通の状態で、thisはグローバル変数windowを指します.
シーン2:
function foo() {
 console.log('     ', this)}
foo() // window
関数内では、thisもグローバル変数windowを指します.
結論一:
正常で、何の呼び出しもない場合、thisはグローバル変数windowを指します.
暗黙のバインディング:
シーン3:
function get() {
 console.log(this.a);}
var obj = {
 a: 2, get}
obj.get() // 2
obj.get呼び出しで、getの中でthisが指すのはobjというオブジェクトです.
場面四:
var obj2 = {
 obj, a: 1}
obj2.obj.get() // 2
二階呼び出しがあっても、thisが指し示すのは一番近い階のthisです.
結論二
これによって、thisが彼のいる関数が呼び出されると、彼はこの関数を指し、彼の一番近い呼び出し対象を指します.
thisがなくなった場合:
この場合は の不足に対する補完である.
シーン5:
function get() {
 console.log(this.a);}
var obj = {
 a: 2, get}
//       :
var getIns = obj.get
getIns() // undefined
もし呼び出し対象が与えられたら、指した後に彼は実際に呼び出し対象がないです.もちろん彼もwindowを指しません.だから、thisはundeを指します.
シーン6:
var o1 = {
 text: 'o1', fn: function () { return this.text }}
var o3 = {
 text: 'o3', fn: function () { console.log('o3', this) var fn = o1.fn return fn() }}
console.log('o3    this    ', o3.fn())  // undefined
o 3のfnで呼び出されても、thisは空のままでこのシーンを指しています.シーン5を強化するための検証です.
結論三:
オブジェクトを呼び出した後に呼び出します.もしバインディングされていないなら、彼の指向は失われます.
なぜなくしましたか
理由は、この書類を読んだら大体分かります.
バインディングを表示
シーン7:
var getIns = obj.get.bind(obj)
getIns() // 2
情景5 thisを使って失われたシーンは、現在印刷されているのが私達の欲しい値です.
シーン8:
var o3 = {
 text: 'o3', fn: function () { var fn = o1.fn return fn.call(this) }}
console.log('   8  o3    this      ', o3.fn()) // undefined
このシーンはcall/applyの2つの関数を使用する役割が同じであり、唯一の違いは、参照:call(this,1,2,3) apply(this, [1,2,3])これらの関数の特別なところ:
var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.log(array); // ["a", "b", 0, 1, 2]
このような方法は、appyによって直接pushされた複数のパラメータが、s 6の後でも早く使用される.
シーン9:
class Foo {
 name = "mike"
 say() { console.log(this.a) }
}
var FooIns = new Foo()
FooIns.say() // undefined
classの中の関数は、これもthisが失われたシーンに属するので、reactに詳しい人はこのシーンを知っているはずです.
newバインディング
ここでいうnewバインディングとシナリオ9は違って、構造関数のバインディングということです.
シーン10
// es5  
function Foo2() {
 this.bar = "LiLz"}
const Foo2Ins = new Foo2()
console.log(Foo2Ins.bar) // LiLz
上のシーンでthisはwindowを指し、シーン10ではnewを通じてFoo 2 Insにthisを結びつけることに成功した.
シーン11
class Foo3 {
 constructor() { this.bar = 'lisa' }}
var Foo3Ins = new Foo3()
console.log(Foo3Ins.bar) // lisa
ここからnewの役割が見られます.方向を変えるのは彼の一部の機能ですが.
結論四
暗黙的/表示呼び出しは、thisの方向を変更することができます.また、暗黙的呼び出しよりも優先度が高いです.
特殊ケース-厳格モード
シーン12
function foo2() {
 'use strict' console.log('       this', this)
}
foo2() // undefined
厳しいモードでは一般的なthisの指向は失われます.
特殊ケース→矢印関数
矢印関数に対応するthisの違いを見てみましょう.
シーン13
const bar = () => {
 'use strict' console.log('    ', this)}
bar() // windows
厳密なモードでも矢印関数のthisはundefinedではありません.
シーン14
const get2 = () => {
 console.log(this, this.a);}
var obj3 = {
 a: 2, get2}
obj3.get2() // window, undefined
暗黙的な呼び出しは、その指向を変更できませんでした.
シーン15
obj3.get2.bind(obj3)() //     14
obj3.get2.call(obj3) //    14
結論5
ここでは、暗黙的/表示呼び出しは矢印関数の方向を変えることができないと結論できます.
シーン16
const Foo4 = () => { this.bar = "LiLz"}
const Foo4Ins = new Foo4()
console.log(Foo4Ins.bar) // TypeError: Foo4 is not a constructor
newに会った時、矢印関数が見えます.彼は構造関数として使えません.
シーン17
class Foo5 {
 name = "mike"
 say = () => { console.log(this.name) }
}
var Foo5Ins = new Foo5()
Foo5Ins.say() // mike
結論6
ここでは、thisの変更の重みが得られます.矢印関数=new>bind/apply/call.
まとめ:
  • は正常で、何の呼び出しもない場合、thisはグローバル変数windowを指す
  • である.
  • this彼がいる関数が呼び出されると、彼は関数を指し、最近の呼び出しオブジェクト
  • を指す.
  • 呼び出し対象が割り当てられた後に呼び出された場合、もしバインディングされたthisがなければ、彼の指向は
  • を失うことになる.
  • 暗黙的/表示呼び出しは、this方向を変更することができ、かつ、暗黙的呼び出しの優先度よりも大きい
  • .
  • 暗黙的/表示呼び出しは矢印関数の指向を変えることができません.矢印関数とnewの構造関数は矛盾しています.
  • this変更の優先度:矢印関数=new>bind/apply/call>関数呼び出し
  • 本論文の全ての例はGitHubにある.http://www.ruanyifeng.com/blo....