JavaScriptでのthisの使い方の詳細な説明

巴扎黑
リリース: 2017-08-21 10:31:19
オリジナル
1286 人が閲覧しました


他の多くのオブジェクト指向言語と同様、JavaScript にも this キーワードがあり、このキーワードは関数内でこのメソッドを呼び出すオブジェクトを指すために使用されます。実際のプログラミングでは、これが誰を指すかを決定するには、一般に次の原則に従うことができます:

  • 関数が Function.call または Function.apply によって呼び出される場合、this は call/apply If の最初のパラメーターを指します。パラメータが null または未定義の場合、これはグローバル オブジェクトを指します (ブラウザでは、グローバル オブジェクトはウィンドウ オブジェクトです)。

  • 関数が Function.bind によって呼び出される場合、これは (メソッドの作成時) binding の最初のパラメーターを指します。

  • 関数がオブジェクトによってメソッドとして呼び出される場合、this はこのオブジェクトを指します。

  • 関数が関数として呼び出されるだけで、オブジェクトにアタッチされていない場合、これはグローバル変数ウィンドウを指します。

関数

まず、「関数」を見てみましょう:

function introduce() {
   alert("Hello, I am Laruence
");
}
ログイン後にコピー

この関数では、this キーワードは誰を指しますか?

グローバルに定義された関数の場合、関数の所有者は現在のページ、つまりウィンドウ オブジェクトです。

そのため、関数を引用符で囲んでいます。グローバルに定義された関数は、実際にはウィンドウ オブジェクトのメソッドであるためです。

そのため、関数名を介して直接呼び出すこともできます。ウィンドウのメソッド名を介して呼び出すことができます。このとき、メソッドの this キーワードはその所有者であるウィンドウ オブジェクトを指します。

ウィンドウの導入属性を確認すると、次の結果が得られます。上記のコードを読むと、グローバル関数はウィンドウ オブジェクトのメソッドであり、グローバル変数はウィンドウ オブジェクトの属性であるため (Javasript スコープですでに説明されています)、グローバル変数には次の方法でアクセスできると思われるかもしれません。グローバル関数の this キーワードですよね?

答えは「はい、introduc 関数を呼び出すと、私を Laruence として認識するでしょう。

イベント処理関数

おそらくこれが混乱の原因のほとんどです。」関数 (メソッド) からのキーワードがイベント処理中に使用されます。

var name = "I am Laruence";
function introduce() {
   alert(this.name);
}
alert(window.introduce);
/**
* output:
* function introduce() {
* alert(this.name);
* }
*/
ログイン後にコピー

たとえば、「名前」入力ボックスをクリックしたときに名前入力ボックスの値を表示する必要がある場合、次のコードを記述できます。 :

<input id="name" type="text" name="name" value="Laruence" />
ログイン後にコピー

上記のコードは、Normal を実行しますが、関数の this ポインタが常に関数の所有者を指しているということは、グローバル変数の所有者が window オブジェクトであることを意味するのではありませんか?

はは、この質問を思いつくことができたということは、あなたが私の記事を真剣に見ているということです、そうでない場合は、最初から読むことをお勧めします、そうしないと、読んだ後も混乱するでしょう〜

そうですね、はい、上記のコードでは、showValue はグローバル オブジェクトで定義されているため、問題は onclick イベント バインディングでのみ発生するようです。決定するときが来ました。

JS 内のすべてがオブジェクトであり、関数やメソッドもプロパティであることはわかっています。したがって、上記のコードでは、onclick をバインドする前に、実際には、name という ID を持つ値を入力ボックス Dom オブジェクトの onclick 属性に割り当てます。関数 showValue を名前入力ボックス オブジェクトの onclick 属性にコピーします。このときの onclick を見ると、次のようになります。つまり、イベントがトリガーされると、名前入力ボックスの onclick メソッドが呼び出されます。このとき、 this キーワードは当然名前入力ボックスを指します

しかし、次のような書き方では、

function showValue() {
   alert(this.value);
}
document.getElementById("name").onclick = showValue;
ログイン後にコピー

が正常に実行できないのですが、なぜですか?

そうですね、現時点では、これは割り当てではなく、参照です。

onclick の 2 つの記述方法に注意を払うと、前のメソッドでは次のように使用しました:

function showValue() {
   alert(this.value);
}
document.getElementById("name").onclick = showValue;
alert(document.getElementById("name").onclick);
/**
* output
* function showValue() {
* alert(this.value);
* }
*/
ログイン後にコピー

前のメソッドでは:

<span class="kwd">function</span><span class="pln"> showValue</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><br/><span class="pln">   alert</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">value</span><span class="pun">);</span><br/><span class="pun">}</span><br/><span class="pun"><</span><span class="pln">input id</span><span class="pun">=</span><span class="str">"name"</span><span class="pln"> type</span><span class="pun">=</span><span class="str">"text"</span><span class="pln"> name</span><span class="pun">=</span><span class="str">"name"</span><span class="pln"> value</span><span class="pun">=</span><span class="str">"Laruence"</span><span class="pln"> onclick</span><span class="pun">=</span><span class="str">"showValue()"</span><span class="pun">/></span>
ログイン後にコピー

これ2 つの違いを反映することもできます。前者は割り当て、後者は参照です。これを行うと、入力ボックスの onclick 属性を確認すると、次のようになります。

dom.onclick = showvalue; //没有调用符
ログイン後にコピー

わかりますか。違いはわかりましたか? 理由はわかりましたか?

この時点で、非常に興味深い例が IE で試してみることができます:

これのポイントを変更してください

さて、理由はわかったので、どうすればよいでしょうか。これを指定したい場所に指定しますか?

上記のイベント処理関数の場合、次の方法で記述できます:

onclick = "showvalue()" //有调用符
ログイン後にコピー
イベント処理関数ではない状況では、apply または call を使用して変更できます。このキーワードのポインタ。

例:

<span class="pln">alert</span><span class="pun">(</span><span class="pln">dom</span><span class="pun">.</span><span class="pln">onclick</span><span class="pun">);</span><br/><span class="com">/**</span><br/><span class="com">* output:</span><br/><span class="com">* function onclick() {</span><br/><span class="com">*  showValue();</span><br/><span class="com">* }</span><br/><span class="com">*/</span>
ログイン後にコピー

関数は Function.call によって呼び出されます:

<img src="xxx" onerror="alert(1);} function hi() { alert(2); " />
ログイン後にコピー

関数が呼び出されます Function.call が呼び出される例:

dom.onclick = showValue();
dom.onclick = function() { alert(this.value) ;}
<input onclick="alert(this.value);" /> //想想刚才我们的引用,是如何把这句嵌入的.
dom.addEventListener(dom, showValue, false); //ff only
ログイン後にコピー

オブジェクトによって呼び出される関数の例:

var laruence = {
   name : "laruence",
   age : 26,
   position : "Senior PHP Engineer",
   company : "Baidu.inc"
};
 
function introduce() {
   alert(this.name);
}
 
introduce.call(laruence);
ログイン後にコピー

深い名前空間で関数を呼び出すとき、コード量を減らすために、呼び出される関数を指す変数をキャッシュします。しかし、そうすると関数内の this の値が変更され、最終的には間違った操作が実行されてしまいます。例:

var myObject = {
  sayHello : function() {
    console.log("Hi! My name is " + this.myName);
  },
  myName : "Rebecca"
};
var secondObject = {
  myName : "Colin"
};
myObject.sayHello();         // logs "Hi! My name is Rebecca"
myObject.sayHello.call(secondObject); // logs "Hi! My name is Colin"
ログイン後にコピー

したがって、コードを保存するために変数をキャッシュしたい場合、正しい方法は、その関数を呼び出すオブジェクトまでのみを保存することです:

var myName = "the global object",
  sayHello = function () {
    console.log("Hi! My name is " + this.myName);
  },
  myObject = {
    myName : "Rebecca"
  };
var myObjectHello = sayHello.bind(myObject);
sayHello();    // logs "Hi! My name is the global object"
myObjectHello(); // logs "Hi! My name is Rebecca"
ログイン後にコピー
つまり、大きな原則があります: その関数を呼び出す人は誰でも、これは誰を指します。

以上がJavaScriptでのthisの使い方の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート