JavaScriptのthis

2823 ワード

this
まず、thisの2つのよくある落とし穴を言います.
自分を指すthisの英語の角度からは、自分自身の感覚を与えやすく、thisが関数自身の考えを指すようになったからである.
function foo(){
    var a = 4;
    console.log(this.a); // undefined
    console.log(this.b); // undefined
    console.log(foo.b);; // 1
}

foo.b = 1;
foo()
thisは、関数自体を指すものではなく、this.bおよびfoo.bは同一ではないことが明らかである.
this指向は関数の作用領域と関係がありますか?
function foo(){
    var a = 4;

    function baz(){
        console.log(a); // 4
        console.log(this.a); // undefined
    }

    baz()
}

foo()
作用するドメインチェーンの方法でaを検索しようとしたが、thisは買わなかった.
では、これからは本当にthisを紹介します.
thisのバインディングルール
thisの結合はどのような規則が使われているかを判断します.全部で四つあります.
標準バインディング
デフォルトのバインディングはthisがwindowを指します.
var a = 4;

function foo(){
    this.bar();
}

function bar() {
    console.log(this.a) // 4
    console.log(window.a) // 4
}

foo()
thisがwindowを指すからこそ、barとaはちょうどwindowの属性としてアクセスできます.
他の規則が適用されない場合、windowにバインドされます.
陰式バインディング
関数がオブジェクトの属性である場合、thisはこのオブジェクトを指します.
var a = 4;

function foo(){
    this.bar(); // 2
    console.log(this.a); // 1
}

var obj = {
    a: 1,
    bar: function(){
        console.log(2)
    },
    foo
}

obj.foo()
これからも、暗黙的なバインディングの優先度はデフォルトのバインディングよりも高いことが分かります.
バインディングを失う
暗黙的なバインディングは操作が間違っていると、バインディングが無くなります.
var a = 4;

function foo(){
    //this.bar();   ,this  window, window  bar  
    console.log(this.a); // 4
}

var obj = {
    a: 1,
    bar: function(){
        console.log(2)
    },
    foo
}

var baz = obj.foo;
baz()
この場合、オブジェクトの関数を変数bazに割り当てますので、bazはfooの参照ですが、それはfoo自体を引用しています.objのfooではないので、この時点でのthisはwindowを指しています.
バインディングを表示call()およびapply()により、thisの指向が変更される.
var a = 4;

function foo(){
    console.log(this.a); // 1
}

var obj = {
    a: 1
}

var obj1 = {
    a: 2
}

function baz() {
    foo.call(obj1); // 2
}

function bar(){
    foo.call(obj)
}
bar(); // 1
baz()
foo(); // 4

foo.call(this )は、this.callを介してthisのオブジェクトを指定することができますが、ここで注意すべきことは、バインディング後、fooのthisは指定のオブジェクトになります.このコードfoo.call()を実行するときだけ、thisは変更され、最後の行コードはfooを単独で呼び出して、thisは依然としてwindowを指します.
newバインディング
newを使って関数を呼び出すか、またはコンストラクターの呼び出しが発生した場合、自動的に次の操作が実行されます.
  • 新たなオブジェクト
  • を作成します.
  • この新しいオブジェクトは[[Prototype]]によって
  • に接続されます.
  • この新しいオブジェクトは、関数呼び出しのthis
  • に結び付けられます.
  • 関数が他のオブジェクトに戻っていない場合、new式の関数呼び出しは自動的にこの新しいオブジェクト
  • に戻ります.
    function foo(a){
        this.a  = a;
        
        this.baz = function(){
            console.log('hellow'+ a)
        }
    }
    var bar = new foo(2);
    console.log(bar.a)
    bar.baz();
    このときthisはnewの実例を指します.