関数呼び出しの4パターンを深く理解する

3263 ワード

前の話
関数はいずれのプログラミング言語としてもコアです.jsに精通したいなら、この面でもっと工夫する必要があります.JavaScriptの関数は対象となります.この文章は多くのブログを見てからまとめたものです.
関数呼び出しの4つのモード
●一般関数としての呼び出し●オブジェクトとしてのメソッド呼び出し●コンストラクター呼び出し●callとappyメソッドの間接呼び出し
一般関数として呼び出す
 function add(x, y) {
         return x + y;
     }
     var sum = add(1, 2);//           
    console.log(sum);
通常の関数での呼び出しは、非厳密モードでは、thisをグローバルオブジェクトに結合し、厳密モードでは、thisはundefinedです.
 function add(x, y) {
         console.log(this);//window
     }
     add();
     function add(x, y) {
         'use strict';
         console.log(this);// undefined
     }
書き換える
通常の関数の呼び出しは、グローバルオブジェクトwindowに結合されますので、グローバル変数は書き換えられます.
    var a = 0;
     function fn() {
         this.a = 2;
     }
     fn();
    console.log(this, this.a, a);// window 2 2
オブジェクトとしてのメソッド呼び出し
関数がオブジェクトの属性として使用される場合、この関数はオブジェクトと呼ばれる方法です.方法が起動されると、thisはオブジェクトに結合されます.
  var obj = {
        fn: function() {
            console.log(this);//  {fn:f}
        }; 
  obj.fn();//               ,  this     obj    
オブジェクトとしてのメソッド呼び出しは、オブジェクトの属性値を取得または変更することができます.
   var obj = {
       a : 1,
       m: function() {
           return this;
       },
       n: function() {
           this.a = 2;
       }
    }
    console.log(obj.m().a);// 1
    obj.n();
    console.log(obj.m().a);// 2
注意:変数と違って、thisはスコープの制限がないので、ネスト関数は呼び出された関数からthisを引き継ぎません.ネスト関数がオブジェクトとなる方法で呼び出された場合、そのthisはこの方法を呼び出すオブジェクトを指します.ネスト関数が普通の関数として呼び出されると、厳密でないモードではWindowsを指し、厳密なモードではundefinedです.
 var obj = {
     m: function() {
         function n () {
             return this;
         }
         return n();//         
     }
 }
 console.log(obj.m());// window
外層にアクセスしたいなら、thisを保存できます.
 var obj = {
     m: function() {
         var that = this;
         function n() {
             return that;
         }
         return n();
     }
 }
 console.log(obj.m() === obj);// true
コンストラクタモード
関数またはメソッドが呼び出される前にnewキーワードがあれば、それは構造関数の呼び出しです.
 function fn() {
     this.a = 1;
 }
 var obj = new fn();
 console.log(obj.a);//1
/*
コンストラクタは通常returnキーを持っていません.この場合コンストラクタコールは新しいオブジェクトを返します.コンストラクタのthisはこのオブジェクトを指します.
 function fn() {
     this.a = 2;
 }
 var test = new fn();
 console.log(test);// {a:2}
コンストラクタがリセットキーを持っていますが、戻り値がない場合は、thisはまだnew fn()に戻る新しいオブジェクトを指します.
 function fn() {
     this.a = 2;
     return ;
 }
 var test = new fn();
 console.log(test);// {a: 2}
コンストラクタにリセットキーがあり、オブジェクトを返します.この時点では新しいオブジェクトは生成されません.testの値は、返ってくるobjオブジェクトです.
 function fn() {
      this.a = 2;
	  return obj;
 }
 var test = new fn();
 console.log(test);// {a: 1}
callとappyメソッドの間接呼び出し
関数の本生も対象です.各関数にはcall()とappy()の方法があります.それらを使って、関数を間接的に呼び出すことができます.call()とappy()は、this指向を変えることができます.二つの方法の役割は同じですが、パラメータリストが異なるだけです.call()とappy()は、チルのもう一つの文章「call()とappy()を深く理解する」を見ることができます.
var obj = {};
function sum(x, y){
    return x + y;
}
console.log(sum.call(obj,1,2));// 3
console.log(sum.apply(obj,[1,3]));// 4
参考:阮一峰先生の文章:http://javascript.ruanyifeng.com/grammar/function.html 他の優れた文章:http://www.cnblogs.com/xiaohuochai/p/5702813.html#anchor1