this, arrow function, call, apply, bind

steyu·2022년 11월 2일
0

메서드란?

객체안에 저장된 함수

메서드는 this로 객체를 참조한다

메서드 단축구문

const user = {
  name: "yu",
  // 1
  sayHi: function () {
    console.log("hi", this.name);
  }

  // 2
  sayHi() {
    console.log("hi", this.name);
  }
}

this란?

함수를 호출한 객체
this는 함수가 호출될 때(런타임) 결정된다. (누가 호출했냐에(콘텍스트)따라 달라진다)

this의 장점?

메서드를 하나만 만들어서 여러 객체에서 재사용이 가능하다 (객체에 따라 this값이 다르기 때문)

function commonSayHi() {
  console.log(this.name);
}

const yu = { name: "yu" };
const stephen = { name: "stephen" };

yu.f = commonSayHi;
stephen.f = commonSayHi;

// 동일한 함수라도 다른 객체에서 호출했다면 'this’가 참조하는 값이 달라집니다
yu.f(); // yu
stephen.f(); // stephen

this의 단점?

위에서 봤다시피, this는 함수를 실행하는 객체에따라 달라지므로 실수하기 쉽다


화살표함수란?

간단한 버전의 함수로, 익명함수다

화살표함수 특징

  • this가 없다
    • this가 없기때문에 화살표함수는 생성자함수로 사용할수 없다 (new와 함께 호출할 수 없다)
    • '누가' 자신을 호출하는지에 대한 정보를 생성하지 않는 것
    • 화살표함수에서 this를 참조하면, 언제나 상위 스코프의 this를 가리킨다.(Lexical this)
    • 또한 call, apply, bind 메소드를 사용하여 this를 변경할 수 없다. 通过 call()apply() 方法调用一个函数时,只能传递参数(不能绑定this),第一个参数会被忽略
function fun() {
  this.num = 123;
}

const arrFuc = () => {
  this.num = 123;
};

const f1 = new fun();
console.log(f1.num); // 123

const f2 = new arrFuc(); // Cannot set properties of undefined (setting 'num')
  • 유사배열인 arguments가 없다
    (this 값과 arguments 정보를 함께 실어 호출을 포워딩해 주는 데코레이터를 만들 때 유용)
// 일반함수
function fun() {
  console.log(arguments); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}

fun(1, 2, 3);

// 화살표함수
const arrFun = () => {
  console.log(arguments); // Uncaught ReferenceError: arguments is not defined
};

fun(1, 2, 3);
  • super이 없다 (외부함수에서 가져옴)
  • 장점은 한줄로 간편하게 사용가능
  • 한줄 함수일때, 인수가 여러개이면 괄호를 생략가능하지만, 없다면 괄호가 필요하다
  • 여러줄 함수일떄, {return }을 써줘야한다

일반함수, 화살표함수 차이점

  • 일반함수의 this는 함수를 호출한 객체를 가리킨다.
  • 화살표함수에서 this는 상위스코프의 this
function func() {
  this.name = "b";
  return {
    name: "a",
    sayHi: function () {
      console.log(this.name);
    }
  };
}

// 위의 func과 같다
function simpleFunc() {
  this.name = "b";
  return {
    name: "a",
    sayHi() {
      console.log(this.name);
    }
  };
}

function arrowFunc() {
  this.name = "b";
  return {
    name: "a",
    sayHi: () => {
      console.log(this.name);
    }
  };
}

const fun1 = new func();
fun1.sayHi();  // a

const fun2 = new arrowFunc();
fun2.sayHi();  // b

화살표함수를 쓰면 안되는 예시

  • 상위스코프에 this가 없는데 화살표함수 메소드에서 this를 사용할때
var dog = {
  lives: 20,
  // 화살표함수
  jumps: () => {
    this.lives--;  // cannot read properties of undefined
  },
  // 일반함수
  jumps: function () {
    this.lives--;
    return this;
  }
};

dog.jumps();

유사배열이란

배열처럼 보이는 가짜배열 (예) obj, 함수의 arguments

function arrayLike() {
 console.log(arguments);
}
arrayLike(4, 5, 6); // Arguments [4, 5, 6, callee, Symbol]

유사배열, 일반배열 차이점

유사배열은 일반배열의 메소드(map, filter, forEach..)를 직접적으로 사용할수 없다

유사배열이 일반배열 메소드 사용하는 법

  1. Array.from()
  2. call, apply
Array.from(nodes).forEach(function(el) { console.log(el) });
Array.prototype.forEach.call(nodes, function(el) { console.log(el); });

유사배열 판단법

  1. Array.isArray()

  2. instanceof (판별할객체 instanceof constructor)


함수의 기본 중요메소드

call, apply, bind

함수를 실행시키는 방법

var example = function (a, b, c) {
  return a + b + c;
};
example(1, 2, 3);
example.call(null, 1, 2, 3);
example.apply(null, [1, 2, 3]);

call은 보통함수와 똑같이 인자를 넣고,
apply는 [인자] 이렇게 하나의 배열로 만들어 넣는다

call은, apply의 첫번째 인자의 역할?

this를 바꿀수 있다

const user = {
  name: "yu",
  yell: function () {
    console.log(this.name);
  }
};

const user2 = {
  name: "stephen"
};

user.yell(); // yu
user.yell.apply(user2); // stephen

this가 가리키는게 user에서 user2로 변했다.
yell은 user의 메소드인데도, user2이 사용했다.
즉 다른 객체의 함수를 자기 것마냥 사용할 수 있다

언제 call, apply 쓰나?

일반함수에서 this를 바꿀때
유사배열이 일반배열 메소드를 쓰고싶을때

function example() {
  console.log(arguments); // 1, string, true
  console.log(arguments.join("")); // arguments.forEach is not a function
  console.log(Array.prototype.join.call(arguments)); // 1,string,true
}

example(1, "string", true);

bind

bind 함수는 함수가 가리키는 this만 바꾸고 호출하지는 않고 함수만 반환한다.
위의 예시와 비교하면

const user = {
  name: "yu",
  yell: function () {
    console.log(this.name);
  }
};

const user2 = {
  name: "stephen"
};

user.yell(); // yu
// user.yell.apply(user2); // stephen  // apply, call
const user2Fuc = user.yell.bind(user2);  // bind는 만 바꾸고 호출하진 않는다
user2Fuc();

call, apply vs bind 차이

셋다 this를 바꾸지만,
bind는 함수를 반환하지 바로 실행하진 않는다.

call(this, 1, 2, 3)은 bind(this)(1, 2, 3)과 같다.

reference

0개의 댓글

관련 채용 정보