JSの「this」を把握する(一)
7678 ワード
一般的には
私たちは一般的に、○○オブジェクトの方法は、「○○オブジェクトの関数」とは言わない.なぜなら、対象に向かって、一つの対象が具体的な例であり、自分なりの方法があるからです.関数は、オブジェクトとは関係ないです.
また、
推荐阅覧:深入浅出ES 6(1~10)シリーズ
一つの言叶でプログラムを书くことができるということは、その言叶を正しく理解して使うということではない.もちろん、JavaScriptもそうです.JS(JavaScriptの略称)はとても使いやすい言語ですが、中にはたくさんの細かいところがあります.初心者はあまり知らないかもしれません.経験豊富なJSの達人でもたまに穴に落ちます.
多くの経験があるプログラマーは
本論文はあなたの考えを整理し、
では、
簡単に言えば、
JavaScript関数を呼び出すたびに、どのようなパラメータが入ってきましたか?関数はどのように呼び出されましたか?関数はどこで呼び出されましたか?などの新しいオブジェクトを作成します.このオブジェクトのもう一つの重要な属性は
ヒント:詳細はECMAScript言語規範§10.4.3節およびその中の関連リンクを参照してください.
すべてのfunctionでは、
行ごとにJavaScriptコードは実行コンテキストで実行されます.
次の例を見ましょう.
functionはどのオブジェクトの方法であるかをすでに知っています.関数では
上記のコードでは、第1回の関数呼び出しに対応するものが
コンテキストを呼び出す
次に、異なる文脈における
グローバルスコープ(Global Scope)
すべてのJavaScriptが実行されている時には唯一のグローバルオブジェクトがあります.ブラウザでは、グローバルオブジェクトは
グローバル実行コンテキスト(任意の関数以外のコード)では、
ローカルスコープ(Local Scope)
関数では、
1.簡単な関数呼び出し(Simple Function Call)に
第一のシナリオは、独立した関数を直接呼び出すことである.
厳密モードであれば、コンテキスト実行時になぜ値が設定されますか?指定されていない場合は、
関数をオブジェクトの属性として保存することで、オブジェクトを介してこの方法を呼び出すことができます.関数をオブジェクトとする方法で呼び出すと、中の
3.コンストラクタFunctionで
私たちは
関数がコンストラクタとして使用されると(
本節では、
JavaScriptでは、すべての関数が対象ですので、関数にも独自の方法があります.すべての関数には二つの方法があります.この2つの方法によって関数のコンテキストを変更することができ、いつでも有効であり、
次は練習します.
最初の関数呼び出しでは、
【
締め括りをつける
So,
おすすめの読書
阮一峰先生の:ECMAScript 6入門
CNBlog:Javascript ContectとScopeの学習まとめ
infoq:深入浅出ES 6(1~10)シリーズ
babeljs-ES 6:https://babeljs.io/repl/
JSの「
JSの「
関連リンク
原文のリンク:Revealing the Inner Working s of JavaScript’s“this”Keyword
日付:2015年5月1日
翻訳日:2015年09月17日
作者:鉄錨http://blog.csdn.net/renfufei
function
を関数に訳し、method
を方法に訳します.私たちは一般的に、○○オブジェクトの方法は、「○○オブジェクトの関数」とは言わない.なぜなら、対象に向かって、一つの対象が具体的な例であり、自分なりの方法があるからです.関数は、オブジェクトとは関係ないです.
また、
scope
(作用領域)およびcontext
(コンテキスト)も、迷いやすいところである.参考してください.Javascript ContectとScopeの学習まとめ推荐阅覧:深入浅出ES 6(1~10)シリーズ
一つの言叶でプログラムを书くことができるということは、その言叶を正しく理解して使うということではない.もちろん、JavaScriptもそうです.JS(JavaScriptの略称)はとても使いやすい言語ですが、中にはたくさんの細かいところがあります.初心者はあまり知らないかもしれません.経験豊富なJSの達人でもたまに穴に落ちます.
多くの経験があるプログラマーは
this
に対してJS内部でどのように動作していますか?通俗的に言えば、this
は別名を引用しているだけです.この別名は現在のオブジェクトだけを知っています.これも一番難しいところです.本論文はあなたの考えを整理し、
this
キーワードの内部動作原理を紹介します.では、
this
は何の鬼ですか?簡単に言えば、
this
は特殊な識別子キーであり、各functionにおいて自動的にスコープに基づいて決定され、今回呼び出した「所有者、owner」を指す.しかし、この問題を完全に解決するには、二つの重要な問題に答える必要があります.this
はどのように作成されましたか?JavaScript関数を呼び出すたびに、どのようなパラメータが入ってきましたか?関数はどのように呼び出されましたか?関数はどこで呼び出されましたか?などの新しいオブジェクトを作成します.このオブジェクトのもう一つの重要な属性は
this
参照であり、関数はどのオブジェクトかの方法であり、this
はこのオブジェクトに自動的にバインドされる.ヒント:詳細はECMAScript言語規範§10.4.3節およびその中の関連リンクを参照してください.
var car = {
brand: "Nissan",
getBrand: function(){
console.log(this.brand);
}
};
car.getBrand();
// output: Nissan
この例では、this.brand
オブジェクトの参照として使用される.したがって、car
はthis.brand
と同等である.car.brand
は誰を指していますか?すべてのfunctionでは、
this
の値は、コンテキスト(context、関数が呼び出し時刻における環境)に基づいて決定される.this
のスコープは、関数が定義する位置に関係なく、関数がどこで呼び出されるかによって決まる.行ごとにJavaScriptコードは実行コンテキストで実行されます.
this
が指すオブジェクトは、新しい実行コンテキストに入るたびに固定され、他の異なるコンテキストに遷移するまで変化する.コンテキストの実行(およびthis
のバインディング)を決定するには、コールポイント(call-site)、コールポイントすなわち関数がコードで呼び出される位置を見つける必要がある.次の例を見ましょう.
var brand = 'Nissan';
var myCar = {brand: 'Honda'};
var getBrand = function() {
console.log(this.brand);
};
myCar.getBrand = getBrand;
myCar.getBrand();
// output: Honda
getBrand();
// output: Nissan
this
およびmyCar.getBrand()
は、同じ関数を指すが、getBrand()
は、どのコンテキストで呼び出されるかによって異なるので、異なるthis
である.functionはどのオブジェクトの方法であるかをすでに知っています.関数では
getBrand()
はこのオブジェクトに結び付けられます.上記のコードでは、第1回の関数呼び出しに対応するものが
this
オブジェクトであり、第2回の対応はmyCar
である.したがって、異なる文脈は異なる結果を生む.コンテキストを呼び出す
次に、異なる文脈における
window
の指向を見てみよう.グローバルスコープ(Global Scope)
すべてのJavaScriptが実行されている時には唯一のグローバルオブジェクトがあります.ブラウザでは、グローバルオブジェクトは
getBrand()
である.Node.jsの中でwindow.getBrand()
です.グローバル実行コンテキスト(任意の関数以外のコード)では、
this
は、厳密なモードであるかどうかにかかわらず、グローバルオブジェクトを指す.ローカルスコープ(Local Scope)
関数では、
window
は、関数がどのように呼び出されるかによって異なります.三つの状況に分けます1.簡単な関数呼び出し(Simple Function Call)に
global
を使用する.第一のシナリオは、独立した関数を直接呼び出すことである.
function simpleCall(){
console.log(this);
}
simpleCall();
// output: the Window object
この場合、this
値はコールされていない.コードは厳密なモードで実行されていないので、strict mode
はまたオブジェクトでなければならないので、彼の値はデフォルトではグローバルオブジェクトです.厳密モードであれば、コンテキスト実行時になぜ値が設定されますか?指定されていない場合は、
this
が続きます.function simpleCall(){
"use strict";
console.log(this);
}
simpleCall();
// output: undefined
2.オブジェクトの方法(Object’s Method)でthis
を使用する.関数をオブジェクトの属性として保存することで、オブジェクトを介してこの方法を呼び出すことができます.関数をオブジェクトとする方法で呼び出すと、中の
this
値が呼び出し方法のオブジェクトとして設定されます.var message = {
content: "I'm a JavaScript Ninja!",
showContent: function() {
console.log(this.content);
}
};
message.showContent();
// output: I'm a JavaScript Ninja!
this
はundefined
オブジェクトの一つの方法であるので、this
はthis
に相当する.3.コンストラクタFunctionで
showContent()
を使用する私たちは
message
オペレータを通じて関数を呼び出すことができます.この場合,この関数は構造関数(すなわち対象工場)になる.上述の単純関数呼び出しと方法呼び出しとは異なり、構造関数呼び出しはthis.content
の値として新しいオブジェクトに入り、新しい構造のこのオブジェクトを結果として暗黙的に返します.関数がコンストラクタとして使用されると(
message.content
キーを介して)、そのthis
値は新しく作成されたそのオブジェクトに結合される.new
キーワードが使用されていない場合、彼はただの普通の関数であり、this
はnew
オブジェクトを指す.function Message(content){
this.content = content;
this.showContent = function(){
console.log(this.content);
};
}
var message = new Message("I'm JavaScript Ninja!");
message.showContent();
// output: I'm JavaScript Ninja!
上記の例では、this
という構造関数がある.new
オペレータを使用して新たなオブジェクトを作成しました.名前はthis
です.また、新しいオブジェクトのwindow
属性として、構造関数の文字列にも伝達されます.最後の行のコードを通して、この文字列は成功的に印刷された.Message()
は新たに作成されたオブジェクトを指すので、構造関数自体ではない.new
をどのように正しく使うか?本節では、
message
の挙動を決定するいくつかの内部メカニズムを学ぶ.JavaScriptでは、すべての関数が対象ですので、関数にも独自の方法があります.すべての関数には二つの方法があります.この2つの方法によって関数のコンテキストを変更することができ、いつでも有効であり、
content
の値を明示的に設定するために使用されます.this
方法は、2つのパラメータを受信する.1つ目はthis
に設定されるオブジェクトであり、2番目のパラメータはオプションであり、パラメータに入るならば、this
の2番目のパラメータとしてパッケージ化すれば良い.this
方法とapply()
は、基本的に同じであり、後のパラメータは配列ではなく、1つずつ分散して後に付加される.次は練習します.
function warrior(speed, strength){
console.log(
"Warrior: " + this.kind +
", weapon: " + this.weapon +
", speed: " + speed +
", strength: " + strength
);
}
var warrior1 = {
kind: "ninja",
weapon: "shuriken"
};
var warrior2 = {
kind: "samurai",
weapon: "katana"
};
warrior.call(warrior1, 9, 5);
// output: Warrior: ninja, weapon: shuriken, speed: 9, strength: 5
warrior.apply(warrior2, [6, 10]);
// output: Warrior: samurai, weapon: katana, speed: 6, strength: 10
ここでは、工場関数this
があります.異なる戦士オブジェクトを導入することによって、異なるタイプのwarrior(戦士)を作成します.では、工場関数内でapply()
は、call()
および/またはapply()
を介して私たちが入ってきたオブジェクトを指す.最初の関数呼び出しでは、
warrior()
方法を用いてthis
をcall()
オブジェクトに設定し、必要な他のパラメータを入力し、パラメータ間をカンマで区切った.第二の関数呼び出しでは、ほとんど同じです.apply()
オブジェクトが入ってきただけで、必要なパラメータを一つの配列にパッケージします.call()
およびthis
に加えて、ECMAScript 5は、関数または方法を呼び出したときにwarrior1
方法によってwarrior2
オブジェクトをバインドすることもできる.次の例を見ましょう.function warrior(kind){
console.log(
"Warrior: " + kind +
". Favorite weapon: " + this.weapon +
". Main mission: " + this.mission
);
}
var attributes = {
weapon: "shuriken",
mission: "espionage"
};
var ninja = warrior.bind(attributes, "ninja");
ninja();
// output: Warrior: ninja. Favorite weapon: shuriken. Main mission: espionage
この例では、call()
方法の使用方法はまだ同様であるが、apply()
は、新しい関数(方法体と作用領域はbind
と同じ)を作成し、従来のthis
関数を変更していない.新しい関数の機能は古いものと同じで、bind()
オブジェクトにのみ結合されています.【
warrior.bind()
方法とwarrior()
、warrior()
との違いは、attributes
の後には関数が実行されず、他の関数に伝達され、ある適切なタイミングで再起動されることである.】締め括りをつける
So,
bind
に関する知識はほとんどこれらです.初心者としては、これらを身につけるだけで十分です.正しく使うことができます.自分に自信を持ってください.もちろん、使用中に問題があるかもしれません.次の記事を読んで、JSの「call
」を把握してください.おすすめの読書
阮一峰先生の:ECMAScript 6入門
CNBlog:Javascript ContectとScopeの学習まとめ
infoq:深入浅出ES 6(1~10)シリーズ
babeljs-ES 6:https://babeljs.io/repl/
JSの「
apply
」を把握する(一)JSの「
bind()
」を把握する(二)関連リンク
原文のリンク:Revealing the Inner Working s of JavaScript’s“this”Keyword
日付:2015年5月1日
翻訳日:2015年09月17日
作者:鉄錨http://blog.csdn.net/renfufei