サーチ…


これは単純なオブジェクトで

var person = {
  name: 'John Doe',
  age: 42,
  gender: 'male',
  bio: function() {
    console.log('My name is ' + this.name);
  }
};
person.bio(); // logs "My name is John Doe"
var bio = person.bio;
bio(); // logs "My name is undefined"

上記のコードでは、 person.bioコンテキストthis )を利用しています 。関数がperson.bio()としてperson.bio()れると、コンテキストは自動的に渡され、「My name is John Doe」というログが正しく記録されます。関数に変数を代入すると、関数はそのコンテキストを失います。

非strictモードでは、デフォルトのコンテキストはグローバルオブジェクト( window )です。厳密モードではundefinedです。

ネストされた関数/オブジェクトで使用するためにこれを保存する

1つの一般的な落とし穴は、コンテキストが失われた入れ子関数またはオブジェクトでthisを試してみることです。

document.getElementById('myAJAXButton').onclick = function(){
    makeAJAXRequest(function(result){
      if (result) { // success
        this.className = 'success';
      }
    })
}

ここでコンテキスト( this )は内部コールバック関数で失われます。これを修正するには、変数の値をthis変数に保存します。

document.getElementById('myAJAXButton').onclick = function(){
    var self = this;
    makeAJAXRequest(function(result){
      if (result) { // success
        self.className = 'success';
      }
    })
}
6

ES6は導入矢印機能字句含まれthis結合を。上記の例は次のように書くことができます:

document.getElementById('myAJAXButton').onclick = function(){
    makeAJAXRequest(result => {
      if (result) { // success
        this.className = 'success';
      }
    })
}

バインディング関数コンテキスト

5.1

すべての関数にはbindメソッドがあり、正しいコンテキストで呼び出すラップ関数を作成します。詳細はこちらを参照してください。

var monitor = {
  threshold: 5,
  check: function(value) {
    if (value > this.threshold) {
      this.display("Value is too high!");
    }
  },
  display(message) {
    alert(message);
  }
};

monitor.check(7); // The value of `this` is implied by the method call syntax.


var badCheck = monitor.check;
badCheck(15); // The value of `this` is window object and this.threshold is undefined, so value > this.threshold is false

var check = monitor.check.bind(monitor);
check(15); // This value of `this` was explicitly bound, the function works.

var check8 = monitor.check.bind(monitor, 8);
check8(); // We also bound the argument to `8` here. It can't be re-specified.

ハードバインディング

  • ハードバインディングの目的は、 thisに対する参照を「ハード」にリンクするthisです。
  • 利点:特定のオブジェクトが失われないように保護する場合に便利です。
  • 例:
function Person(){
    console.log("I'm " + this.name);
}

var person0 = {name: "Stackoverflow"}
var person1 = {name: "John"};
var person2 = {name: "Doe"};
var person3 = {name: "Ala Eddine JEBALI"};

var origin = Person;
Person = function(){
    origin.call(person0);
}

Person();
//outputs: I'm Stackoverflow

Person.call(person1);
//outputs: I'm Stackoverflow


Person.apply(person2);
//outputs: I'm Stackoverflow


Person.call(person3);
//outputs: I'm Stackoverflow
  • したがって、上の例では、 Personに渡すオブジェクトが何であれ、 person0オブジェクトを使用しますつまり、バインドは 難しいです。

これはコンストラクタ関数で

ファンクションをコンストラクタとして使用する場合、 thisバインディングは特別に作成され、新しく作成されたオブジェクトを参照します。

function Cat(name) {
  this.name = name;
  this.sound = "Meow";
}

var cat = new Cat("Tom"); // is a Cat object
cat.sound; // Returns "Meow"

var cat2 = Cat("Tom"); // is undefined -- function got executed in global context
window.name; // "Tom"
cat2.name; // error! cannot access property of undefined


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow