ホームページ > 記事 > ウェブフロントエンド > JavaScript でこのポインタが指すものを探る_基礎知識
このポインタが JavaScript で何を指しているのかを調べてください
まず第一に、this のポイントは関数が定義された時点では決定できないということです。実際、this が最終的に誰を指すのかを決定することができます。この文にはいくつか問題があります。なぜ問題があるのかは後ほど説明します。インターネット上のほとんどの記事にはこのように書かれていますが、多くの場合、そのように理解して問題ありませんが、実際には、このように理解するのは不正確です。したがって、これを理解すると不確実性が生じます)。次に、この問題について詳しく説明します。
なぜこれを学ぶ必要があるのですか?関数型プログラミングやオブジェクト指向プログラミングを学習したことがある方は、それが何に使われるかを必ず知っています。まだ学習していない方は、当面この記事を読む必要はありません。興味があるなら、これはマスターする必要があるものです。
例 1:
function a(){ var user = "追梦子"; console.log(this.user); //undefined console.log(this); //Window } a();
上で述べたように、これは最終的にそれを呼び出すオブジェクトを指します。次のコードが証明するように、ここでの関数 a は実際には Window オブジェクトによって指し示されます。
function a(){ var user = "追梦子"; console.log(this.user); //undefined console.log(this); //Window } window.a();
実際には、アラートもウィンドウの属性であり、ウィンドウごとにクリックされます。
例 2:
var o = { user:"追梦子", fn:function(){ console.log(this.user); //追梦子 } } o.fn();
ここでは、this はオブジェクト o を指します。これは、この fn を呼び出すと、o.fn() を通じて実行されるため、自然な点はオブジェクト o です。this の点は、いつ決定されるかは決定できないことをもう一度強調しておきます。はい、呼び出し時に誰が誰を指すのかを決定できます。
実際、例 1 と例 2 は十分に正確ではありません。次の例は上記の理論を覆す可能性があります。
これを完全に理解したい場合は、次のいくつかの例を読む必要があります
例 3:
var o = { user:"追梦子", fn:function() { console.log(this.user); //追梦子 } } window.o.fn();
このコードは上記のコードとほぼ同じですが、なぜここでは window を指していないのでしょうか? 上記の理論によれば、最終的に this はそれを呼び出すオブジェクトを指していることになります。 ここで余談ですが、 window です。 js のグローバル オブジェクト。作成した変数は実際にウィンドウに属性を追加するため、ここではウィンドウ ドット オブジェクトを使用できます。
上記のコードのこのコードがウィンドウを指していない理由は説明しません。コードの一部を見てみましょう。
var o = { a:10, b:{ a:12, fn:function(){ console.log(this.a); //12 } } } o.b.fn();
ここでもオブジェクト o が指摘されていますが、これも実行されません。そうすると、最初に言ったことは間違いだと言われますね。実際にはそうではなく、最初に述べたことが不正確だっただけです。次に、これで指摘されている問題を完全に理解できると思います。
ケース 1: 関数内に this があるが、上位レベルのオブジェクトによって呼び出されない場合、this は window を指します。ここで注意する必要があるのは、厳密なバージョンの js では this がそうではないということです。ウィンドウを指してください。ただし、ここでは厳密なバージョンについては説明しません。詳しく知りたい場合は、オンラインで検索してください。
ケース 2: 関数内に this があり、この関数が上位レベルのオブジェクトによって呼び出される場合、this は上位レベルのオブジェクトを指します。
ケース 3: 複数のオブジェクトを含む関数内に this がある場合、その関数が最も外側のオブジェクトによって呼び出されている場合でも、信じられない場合は、例 3 で証明できるのはその上のオブジェクトのみです。それでは、続けていくつかの例を見てみましょう。
var o = { a:10, b:{ // a:12, fn:function(){ console.log(this.a); //undefined } } } o.b.fn();
オブジェクト b には属性 a はありませんが、このオブジェクトに必要なものがあるかどうかに関係なく、これはその上位レベルのオブジェクトのみを指すため、これもオブジェクト b を指します。
さらに特殊な状況もあります。例 4:
var o = { a:10, b:{ a:12, fn:function(){ console.log(this.a); //undefined console.log(this); //window } } } var j = o.b.fn; j();
これはウィンドウを指します。混乱していますか?実際、それはあなたが文章を理解していなかったからであり、これも重要です。
これは常に、最後に呼び出したオブジェクト、つまり実行時に呼び出したオブジェクトを指します。例 4 では、関数 fn はオブジェクト b によって参照されますが、fn が変数 j に代入されるときには代入されません。これは実行されないため、最終的に window を指します。これは、fn を直接実行する例 3 とは異なります。
これは実際には同じことですが、状況が異なると異なるものを示します。上記の要約には、エラーとは言えない小さな間違いがいくつかありますが、環境が異なると、次の状況は異なります。時間があるので一度にわかりやすく説明することはできませんが、ゆっくりと体験していただくしかありません。
これのコンストラクターバージョン:
function Fn(){ this.user = "追梦子"; } var a = new Fn(); console.log(a.user); //追梦子
这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例,理解这句话可以想想我们的例子3,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象Fn中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。
除了上面的这些以外,我们还可以自行改变this的指向,关于自行改变this的指向请看JavaScript中call,apply,bind方法的总结这篇文章,详细的说明了我们如何手动更改this的指向。
更新一个小问题当this碰到return时
function fn() { this.user = '追梦子'; return {}; } var a = new fn; console.log(a.user); //undefined
再看一个
function fn() { this.user = '追梦子'; return function(){}; } var a = new fn; console.log(a.user); //undefined
再来
function fn() { this.user = '追梦子'; return 1; } var a = new fn; console.log(a.user); //追梦子 function fn() { this.user = '追梦子'; return undefined; } var a = new fn; console.log(a.user); //追梦子
什么意思呢?
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
function fn() { this.user = '追梦子'; return undefined; } var a = new fn; console.log(a); //fn {user: "追梦子"}
还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。
function fn() { this.user = '追梦子'; return null; } var a = new fn; console.log(a.user); //追梦子
知识点补充:
1.在严格版中的默认的this不再是window,而是undefined。
2.new操作符会改变函数this的指向问题,虽然我们上面讲解过了,但是并没有深入的讨论这个问题,网上也很少说,所以在这里有必要说一下。
function fn(){ this.num = 1; } var a = new fn(); console.log(a.num); //1
为什么this会指向a?首先new关键字会创建一个空的对象,然后会自动调用一个函数apply方法,将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。