コアJavaScript 03 this


初めて見たコンセプトなので分かりづらいですが、要約すると、いつか成功すると信じています、、、がんばれ@@️
JavaScriptではどこでも利用できます.これは関数とオブジェクト(メソッド)の間のばらばらな区分のJavaScriptで両者を区別している.

✔状況によって変わるこの


これは関数を呼び出すときに決定されます.

グローバルスペース


異なるランタイム環境には、異なる名前と情報があります.ブラウザ-window,Node.js-global.
console.log(this);
console.log(window);
console.log(this===window); //true

//전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당한다. 
var a =1;
console.log(a); //1(window. 생략된 것)
console.log(window.a); //1
console.log(this.a); //1
//주의
/*
전역변수로 선언한 경우 삭제가 되지 않음
자동으로 전역객체의 프로퍼티로 할당하며 해당 프로퍼티의 변경 및 삭제가능성을  false로 정의
*/
var a = 1;
delete window a; //false
//처음부터 전역객체의 프로퍼티로 할당한 경우 삭제 가능
window b = 2;
delete window b; //true
/*
var로 선언한 전역변수와 전역객체의 프로퍼티는 
호이스팅 여부, 변경 및 삭제 가능성 여부에서 차이를 보임
*/

メソッド呼び出し時


独立した機能を実行する関数とは異なり、メソッドは自分のターゲットオブジェクトを呼び出す操作を実行します.メソッド呼び出しトピック(メソッド名の前のオブジェクト).
//메서드로 호출
var func = function (x) {
  console.log(this, x);
}  
func(1); //Window {...} 함수로 호출 

var obj = {
  method :func
};
obj.method(2); //{method: f} 2 메서드로 호출

関数呼び出し時


関数の内部では、グローバルオブジェクトを参照します.関数を呼び出すと、thisは指定されません.関数呼び出しとしては、開発者がコードに直接関与して実行し、呼び出しトピックは指定されていません.△これは設計上の誤りだという指摘もある.
メソッド内部関数では、thisもグローバルオブジェクトを参照します.
var obj1 = {
  outer: function() {
    console.log(this);//obj1
    //obj1.outer() 메서드로서 호출.
    var innerFunc = function () {
      console.log(this);//window
      //함수로서 호출.
    }
    innerFunc();
    
    var obj2 = {
      innerMethod: innerFunc
    };
    obj2.innerMethod();//obj2
    //메서드로서 호출
  }
};
obj1.outer();
上記の例から、関数の内部かメソッドの内部かは重要ではありませんが、この関数を呼び出す場合、文法の前に点または角カッコタグ(メソッド呼び出し)があるかどうかがより重要です.
では、関数内でトピックが呼び出されていないときにグローバルオブジェクトを自動的にバインドし、呼び出されたときに周囲の環境を直接継承する方法はありませんか?これはES 6環境で矢印関数を用いて解決できる.関数の内部にはthisはありません.アクセスする場合はscopeチェーンで最近のthisにアクセスします.
var obj = {
  outer : function() {
    console.log(this);
    var innerFunc = () => {
      console.log(this);
    };
    innerFunc();
  }
};
obj.outer();
実行コンテキストを作成すると、矢印関数はバインドプロセス自体を無視します.そのため、上司のこの点を直接利用することができます.

コールバック関数


コールバック関数の制御権を渡す関数に基づいて定義され、定義されていない場合はグローバルオブジェクトが参照されます.
// 300ms 만큼 시간 지연한 뒤 콜백 함수를 실행하라는 명령
// 0.3초 뒤 전역객체 출력
// this 지정 x, 전역객체
setTimeout(function () {console.log(this); }, 300);

//전역객체와 배열의 각 요소 5회 출력
// this 지정 x, 전역객체
[1, 2, 3, 4, 5].forEach(function (x) {
  console.log(this, x);
});

//이벤트 발생할 때 마다 이벤트 정보를 콜백 함수의 첫 번째 인자로 삼아 함수 실행
//버튼 클릭시 앞서 지정한 엘리먼트와 클릭 이벤트에 관한 정보가 담긴 객체 출력
//.addEventListener은 자신의 this를 상속하도록 정의되어 있음. .의 앞부분이 this
document.body.innerHTML += '<button id="a">클릭</button>;
document.body.querySelector('#a')
	.addEventListener('click', function (e) {
  		console.log(this,e);	
	});

コンストラクション関数


作成するインスタンスを参照してください.
コンストラクション関数は、いくつかの共通の性質を持つオブジェクトを作成するための関数です.オブジェクト向け言語では、クラス、クラスで作成されたオブジェクトをインスタンスと呼びます.ジェネレータは、特定のインスタンスを作成するフレームワークと言える.このフレームワークは、クラスの共通属性を提供し、インスタンスの個性を追加して単一のインスタンスを作成できます.
JAvascriptは関数を構築関数として与える役割を果たす.newコマンドと関数を呼び出すと、この関数はコンストラクション関数として動作します.関数がコンストラクション関数として呼び出されると、内部のthisは新しく作成されたインスタンスになります.
var Dog = function (name, age) {
  this.bark = '멍멍';
  this.name = name;
  this.age = age;
};
var darling = new Dog('달링', 6);
console.log(darling)
/*
{
  age: 6,
  bark: "멍멍",
  name: "달링"
}
*/

✔この項目を明示的にバインドする


call & apply


関数またはメソッドを明示的に指定して呼び出す

call


メソッド呼び出しの主体である関数を直ちに実行するコマンドです.callメソッドの最初のパラメータをthisにバインドし、後でこれらのパラメータを呼び出す関数のパラメータとします.
Function.prototype.call(thisArg[,arg1[,arg2[, ...]]])
//함수
var func = function (a, b, c) {
  console.log(this, a, b, c);
};

func(1, 2, 3); //window{...} 1 2 3
func.call({x: 1}, 4, 5, 6);//{x: 1} 4 5 6

//메서드
var obj = {
  a: 1,
  method : function(x, y) {
    console.log(this.a, x, y);
  }
};

obj.method(2, 3);//1 2 3
obj.method.call({a: 4}, 5, 6); //4 5 6

apply


コールと機能は同じです.しかしapplyメソッドは、2番目のパラメータを配列として受け入れ、その配列の要素呼び出しのパラメータとして関数を指定します.
Function.prototype.appy(thisArg[, argsArray])
//함수
var funcc = function(a,b,c) {
  console.log(this, a, b, c);
};
func.apply({x: 1}, [4, 5, 6]); //{x: 1} 4 5 6
//메서드
var obj = {
  a: 1,
  method: function (x, y) {
    console.log(this.a, x, y);
  }
};
obj.method.apply({a: 4}, [5, 6]); // 4 5 6

call/applyメソッドの利用


コンストラクション関数の内部で他のコンストラクション関数を呼び出す


コンストラクション関数の内部に他のコンストラクション関数と共通の内容がある場合は、call/applyを呼び出して他のコンストラクション関数を呼び出すことで、重複を減らすことができます.
function Person(name, gender) {
  this.name = name;
  this.gender = gender;
}
function Student(name, gender, school) {
  Person.call(this, name, gender);
  this.school = school;
}

var db = newStudent('달링', 'male', '귀염대');

複数の引数を1つの配列にマージします。


パラメータを配列として複数の受信パラメータに渡す方法.
//Math.max와 Math.min 메서드를 적용해 배열의 최대/최솟값을 구해보자.
var numbers = [10, 30, 55, 43, 52];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
console.log(max, min); // 55 10
call/apply法の欠点は予測が困難であり,解釈を妨げることである.しかしES 5以下の環境では代替案がないため広く用いられている.

bind


2つの目的があります.この機能を関数に事前に適用し、一部の適用関数を実装します.callと同様ですが、すぐに呼び出すのではなく、受信したthisとパラメータに基づいて新しい関数を返します.
var func = function (a, b, c, d) {
  console.log(this, a, b, c, d);
};

var bindFunc1 = func.bind({x: 1});
bindFunc1(5, 6, 7, 8); // {x:1} 5 6 7 8

//bind 메서드를 적용하면 name 프로퍼티에 bound 라는 접두어가 붙는다. 
console.log(bindFunc1.name); //bound func

このパラメータが個別のパラメータとして受信された場合(コールバック関数)


パラメータとしてコールバック関数を受信する方法によっては、このパラメータとして指定するオブジェクト(thisArg)を指定できます.主に配列方法に配置されます.
var report= 
    sum:0,
    count:0,
    
    add: function(){
    //arguments를 배열로 변환해 args 변수에 담고
      var args = Array.prototype.slice.call(arguments);
      //이 배열을 순회하며 콜백함수 실행
      args.forEach(function (entry) {
        this.sum += entry;
        ++this.count;
        //forEach 함수의 두번째 인자로 전달한 아래 this가 바인딩 된다.
      }, this);
    },
    average: function () {
      return this.sum / this.count;
    }
};
report.add(60, 85, 95);
//세 인자를 배열로 만들어 forEach 메서드가 실행된다. 
//콜백함수 내부에서 this는 add 메서드에서의 this(report)를 가리킴
//따라서 배열 세 요소를 순환하며 값이 차례로 바뀜
console.log(report.sum, report.count, report.average()); 
//240 3 80