ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript でこのオブジェクトを理解する (コード例)

JavaScript でこのオブジェクトを理解する (コード例)

不言
不言転載
2018-10-29 14:29:122363ブラウズ

この記事は JavaScript でのこのオブジェクトの理解に関するものです (コード例)。必要な方は参考にしていただければ幸いです。

前書き: 最近『JavaScript Advanced Programming』を読んでいますが、この本の中国語版には不十分な翻訳がたくさんあるので、自分の理解している範囲で解釈するようにしています。間違いや漏れがございましたら、ご指摘いただければ幸いです。この記事の内容のほとんどは『JavaScript Advanced Programming, Third Edition』から引用しています。

このオブジェクトは、実行時の関数の実行環境バインディングに基づいています:

グローバル環境では、これはウィンドウに相当し、関数がオブジェクトのメソッドとして呼び出されるとき、これはそのオブジェクトを指します。

ただし、匿名関数の実行環境はグローバルであるため、このオブジェクトは通常 window を指します。

このオブジェクトをクロージャ内で使用すると、問題が発生する可能性があります。

クロージャの記述方法によっては、これがあまり明白でない場合があります。

// 在全局环境中,this等于window
function thisBoundForWindow(){
    console.log(this);
    console.log(this.name);
}
thisBoundForWindow(); // Window
var o = new Object();
o.name = "Shaw";
//当函数被作为某个对象的方法调用时,this就指向了那个对象。
thisBoundForWindow.apply(o); // {name: "Shaw"}; "Shaw" ;
//在闭包中使用this对象可能会导致一些问题。
//有时候由于编写闭包的方式不同,这一点可能不会那么明显。
var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function() {
        return function() {
            console.log(this.name);
        }
    }
}
object.getNameFunc()(); // "The Window"
/*
object.getNameFunc return=> function() {
        return function() {
            console.log(this.name);
        }
    }  => ()调用,还是在全局环境下调用的,所以this.name = window.name => "The Window"
*/

上記のコードは、まずグローバル変数名を作成し、次に name 属性を含むオブジェクトを作成します。

このオブジェクトには、匿名関数を返すメソッド getNameFunc() も含まれており、この匿名関数は this.name を返します。

「クロージャ」の定義を確認してみましょう:

別のスコープ内の変数にアクセスできる関数はクロージャです。

getNameFunc() は関数を返すため、object.getNameFunc()() を呼び出すと、返される関数が呼び出され、その結果、文字がコンソールに出力されます。

ただし、この例で返される文字は「The Window」であり、これはグローバル名変数の値です。

それでは、これを例のオブジェクトを指すようにするにはどうすればよいでしょうか?

this オブジェクトを外部スコープのクロージャがアクセスできる変数に保存し、クロージャがオブジェクトにアクセスできるようにします。 (このメソッドはコールバック関数を使用するときにもよく使用されることに注意してください)。

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function(){
        var that = this;
        return function() {
            console.log(that.name);
        }
    }
}
object.getNameFunc()(); // "My Object"
/*
// 伪代码过程
object.getNameFunc  execute
=> this = object = that 
=>function() {console.log(that.name);}  
=> ()
=> that.name = object.name 
=> "My Object" 
*/

匿名関数を定義する前に、this オブジェクトを that という名前の変数に割り当てます。

クロージャを定義した後、クロージャはこの変数にアクセスすることもできます。これは、それを含む関数内で特別に宣言した変数であるためです。

関数が戻った後でも、それはオブジェクトを参照しているため、Object.getNameFunc() を呼び出すと「My Object」が返されます。

いくつかの特殊な状況では、この値が予期せず変更される可能性があります。たとえば、次のコードは前の例の結果を変更します。

var name = "The Window";
var object = {
    name: "My Object",
    getName: function() {
        console.log(this.name);
    }
};
object.getName(); // "My Object"
(object.getName)(); // "My Object"
(object.getName = object.getName)(); // "The Window"

コードの最初の行は、通常どおり object.getName() を呼び出し、this.name が object.name であるため、「My Object」を返します。

コードの 2 行目は、このメソッドを呼び出す前に括弧を追加していますが、括弧を追加した後は関数を参照しているように見えますが、object.getName と (object .getName) の定義が定義されているため、この値は維持されます。同じ。

コードの 3 行目では、まず代入ステートメントを実行し、次に代入の結果を呼び出します。代入式は関数そのものであるため、this の値は保持されず、「The Window」が返されます。

//第三个例子伪代码
//理解此段代码,首先要明确一个知识点:赋值语句是有返回值的,返回值就是所赋的值(也就是‘=’右边的值)。

(object.getName = object.getName)(); // "The Window"

(object.getName = function(){ console.log(this.name)})();

(function(){console.log(this.name)})();
//所以this指向window

もちろん、コードの 2 行目と 3 行目のようにこのメソッドを呼び出すことはほとんどありません。当面は理解できなくても大丈夫です。この例は、構文の微妙な変更によっても this の値が誤って変更される可能性があることを示しています。

以上がJavaScript でこのオブジェクトを理解する (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。