JavaScriptシリーズを深く理解する(一):関数の4つの呼び出しモード


ここ1、2ヶ月からフロントエンドに向かい、グループの牛たちと一緒にデータ分析と展示のプロジェクトをしています.フロントエンドは私が去年大学3年生の時に思ったほど簡単で浅薄ではありません.今流行しているリッチクライアント+RESTモードはフロントエンドの開発を大いに可能にしています.続々とjsに関する本を何冊も読んで、jsに対してもっと深い認識と理解があって、自分の前のいくつかの困惑を解決しました.だからシリーズを书きたいと思って、JSの中でいくつか困惑する知识の点を话して、JSの基础を学ぶことができることを望んで、しかしJSに対して理解していない学友に少し助けます.
ここではまずJSにおける関数の呼び出しパターン,あるいはJSにおけるthisの指向問題について述べる.

1.メソッド呼び出しモード


関数がオブジェクトのプロパティとして保存されると、メソッドと呼ばれます.メソッドが呼び出されると、thisはオブジェクトにバインドされます.
function A() {
       this.x = 1;    //  a.x
       this.b = function () {    //  a.b
            this.helper = function () {     //  a.helper
       	          console.log(this);  //4.console.log(a)
            }
            this.helper();  //3.  a.helper();    helper,     ,  helper  this  a
       }
       this.b();    //2.  a.b(),   b a     ,       ,  b  this  a
}
var a = new A(); //1.  a  

出力:A{x:1}

2.関数呼び出しモード


関数がオブジェクトのプロパティでない場合、関数として呼び出されます.このときthisはグローバルオブジェクトにバインドされます.
function A() {
	this.x = 1;    
        this.b = function () {
              var helper = function () {
       		      console.log(this);
               }
              helper();  //   helper         ,      
        }
        this.b();
}
var a = new A(); 

出力:Window{external:Object,......}

3.コンストラクタ呼び出しモード


newキーを使用すると、thisは作成された新しいオブジェクトにバインドされます.
function A() {
    this.x = 1;    
    this.b = function () {
  	this.helper = function () {   //  aa.helper
       	    console.log(this); //4.console.log(aa)
        }
      this.helper(); //3.  aa.helper();    helper,     ,  helper  this  aa
    }
    var aa = new this.b();   //2.        aa,  b()  this  aa
}
var a = new A(); //1.  a  

出力:A.b{};
また、ここではSplunkマスコットponyの例を挙げてnewオペレータがすることを説明します.
function Pony(color) {
    // var this = Object.create(Pony.prototype);
 
    // instance members
    this.color = color;
 
    // private members
    var age = 50;
 
    // private methods
    function secreteMethod() {
        console.log('Secret!');
    }
 
    // make private member visible due to closure
    this.getAge = function() {
        console.log('My age is : ' + age);
    };
 
    // return this;
}
 
// methods
Pony.prototype.tellColor = function() {
    console.log('I am ' + this.color);
};
 
// static attributes
Pony.type = 'horse';
 
var pony = new Pony('white');
pony.tellColor();
pony.getAge();

what happens?
var pony = new Pony('white');
// equals
var pony = {};
pony.__proto__ = Pony.prototype;
Pony.call(pony, 'white');

4.apply呼び出しモード


jsは関数式のオブジェクト向けプログラミング言語であるため,関数には方法がある.apply(or call)メソッドでは、パラメータ配列を構築して呼び出し関数に渡すことも、thisの値を選択することもできます.2つのパラメータを受け入れます.1つ目はthisにバインドする値で、2つ目はパラメータ配列です.
function People (name) {
		this.name = name;
} 
People.prototype.greet = function () {
		console.log('hi,'+this.name);
};
var dog = {
	name: 'hobbo'
};
People.prototype.greet.apply(dog);
出力:hi,hobbo
まとめ:
  • thisデフォルトはglobal object
  • を指します.
  • 関数がオブジェクトの属性として呼び出されると、関数のthisはそのオブジェクト
  • を指す.
  • newオペレータを使用して関数を呼び出すと、関数のthisは新しく作成されたオブジェクト
  • を指します.
  • applyまたはcallを使用して関数を呼び出すと、thisはcallアクティブapplyに渡される最初のパラメータを指す.最初のパラメータが空またはオブジェクトでない場合、thisはglobal object
  • を指します.