js でこの関数を呼び出すいくつかの方法

零到壹度
リリース: 2018-05-18 10:14:57
オリジナル
1850 人が閲覧しました

これは JavaScript では非常に豊富な意味を持ち、グローバル オブジェクト、現在のオブジェクト、または任意のオブジェクトにすることができ、すべては関数の呼び出し方法によって異なります。関数は、オブジェクト メソッドとして、関数として、コンストラクターとして、適用または呼び出しの方法で呼び出すことができます。

オブジェクトメソッド呼び出し

オブジェクトメソッドとして呼び出された場合、オブジェクトにバインドされます。

  1. var point = {   
     x : 0,   
     y : 0,   
     moveTo : function(x, y) {   
         this.x = this.x + x;   
         this.y = this.y + y;   
         }   
     };   
      
     point.moveTo(1, 1)//this 绑定到当前对象,即 point 对象
    ログイン後にコピー

ここで 1 つ強調しておきたいのは、関数の定義時ではなく、関数の実行時に対応する値を取得するということです。オブジェクトのメソッド呼び出しであっても、メソッドの関数属性を関数名という形で別のスコープに渡すと、そのポインタが変更されます。例を挙げましょう:

  1. var a = {  
        aa : 0,  
        bb : 0,  
        fun : function(x,y){  
            this.aa = this.aa + x;  
            this.bb = this.bb + y;  
        }  
    };  
    var aa = 1;  
    var b = {  
        aa:0,  
        bb:0,  
        fun : function(){return this.aa;}  
    }     
    a.fun(3,2);  
    document.write(a.aa);//3,this指向对象本身  
    document.write(b.fun());//0,this指向对象本身  
    (function(aa){//注意传入的是函数,而不是函数执行的结果  
        var c = aa();  
        document.write(c);//1 , 由于fun在该处执行,导致this不再指向对象本身,而是这里的window  
    })(b.fun);
    ログイン後にコピー

以上です。ここはややこしいところかもしれません。

関数呼び出し

このとき、関数はグローバルオブジェクトにバインドされて直接呼び出すこともできます。

  1. var x = 1;  
     function test(){  
       this.x = 0;  
     }  
     test();  
     alert(x); //0
    ログイン後にコピー

しかし、これはいくつかの問題を引き起こします。つまり、関数内で定義された関数の場合、これはグローバルな世界も指すことになり、これは私たちが望んでいることとはまったく逆です。コードは次のとおりです:

  1. var point = {   
     x : 0,   
     y : 0,   
     moveTo : function(x, y) {   
         // 内部函数  
         var moveX = function(x) {   
         this.x = x;//this 绑定到了全局  
        };   
        // 内部函数  
        var moveY = function(y) {   
        this.y = y;//this 绑定到了全局  
        };   
      
        moveX(x);   
        moveY(y);   
        }   
     };   
     point.moveTo(1, 1);   
     point.x; //==>0   
     point.y; //==>0   
     x; //==>1   
     y; //==>1
    ログイン後にコピー

必要な動きの効果が完了していないだけでなく、さらに 2 つのグローバル変数があることがわかります。では、どうすれば解決できるでしょうか?関数内で関数を入力するときにこれを変数に保存し、その変数を使用するだけです。コードは次のとおりです:

  1. var point = {   
     x : 0,   
     y : 0,   
     moveTo : function(x, y) {   
          var that = this;   
         // 内部函数  
         var moveX = function(x) {   
         that.x = x;   
         };   
         // 内部函数  
         var moveY = function(y) {   
         that.y = y;   
         }   
         moveX(x);   
         moveY(y);   
         }   
     };   
     point.moveTo(1, 1);   
     point.x; //==>1   
     point.y; //==>1
    ログイン後にコピー

コンストラクター呼び出し

JavaScript でコンストラクターを自分で作成する場合、これを使用して新しく作成されたオブジェクトを指すことができます。こうすることで、グローバル

  1. var x = 2;  
     function test(){  
       this.x = 1;  
     }  
     var o = new test();  
     alert(x); //2
    ログイン後にコピー

apply または call

を指す関数でこれを回避できます。これら 2 つのメソッドは、関数実行のコンテキストを切り替えることができます。つまり、これにバインドされているオブジェクトを変更できます。 apply と call は似ていますが、パラメータを渡すときの 1 つの要件は配列であり、もう 1 つの要件はそれらが別々に渡されることです。それでは例として apply を見てみましょう:

  1. <pre name="code" class="html">var name = "window";  
          
    var someone = {  
        name: "Bob",  
        showName: function(){  
            alert(this.name);  
        }  
    };  
      
    var other = {  
        name: "Tom"  
    };     
       
    someone.showName();     //Bob  
    someone.showName.apply();    //window  
    someone.showName.apply(other);    //Tom
    ログイン後にコピー

オブジェクト内のメソッドに通常アクセスすると、これがオブジェクトを指していることがわかります。 apply を使用した後、apply にパラメーターがない場合、this の現在のオブジェクトはグローバル オブジェクトになります。 apply にパラメーターがある場合、this の現在のオブジェクトはパラメーターになります。

アロー関数呼び出し

ここで追加すべきことの 1 つは、次世代 JavaScript 標準 ES6 では、arrow 関数の this は、関数が定義されたときではなく、常に this を指すということです。実行されます。例を通して理解しましょう

  1. var o = {  
        x : 1,  
        func : function() { console.log(this.x) },  
        test : function() {  
            setTimeout(function() {  
                this.func();  
            }, 100);  
        }  
    };  
      
    o.test(); // TypeError : this.func is not a function
    ログイン後にコピー

上記のコードは、 this のポインタが o から global に変わるため、エラーが発生します。上記のコードを次のように変更する必要があります:

  1. var o = {  
        x : 1,  
        func : function() { console.log(this.x) },  
        test : function() {  
            var _this = this;  
            setTimeout(function() {  
                _this.func();   
            }, 100);  
        }  
    };  
      
    o.test();
    ログイン後にコピー

通过使用外部事先保存的this就行了。这里就可以利用到箭头函数了,我们刚才说过,箭头函数的 this始终指向函数定义时的 this,而非执行时。所以我们将上面的代码修改如下:

  1. var o = {  
        x : 1,  
        func : function() { console.log(this.x) },  
        test : function() {  
            setTimeout(() => { this.func() }, 100);  
        }  
    };  
      
    o.test();
    ログイン後にコピー

这回this就指向o了,我们还需要注意一点的就是这个this是不会改变指向对象的,我们知道call和apply可以改变this的指向,但是在箭头函数中是无效的。

  1. var x = 1,  
        o = {  
            x : 10,  
            test : () => this.x  
        };  
      
    o.test(); // 1  
    o.test.call(o); // 依然是1
    ログイン後にコピー

这样就可以明白各种情况下this绑定对象的区别了。

以上がjs でこの関数を呼び出すいくつかの方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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