자바스크립트 (스코프, this)

이종경·2024년 4월 14일
0

자바스크립트

목록 보기
5/11
post-thumbnail

1. 자바스크립트는 기본적으로 함수 스코프를 따른다.

함수 레벨 스코프란 함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 유효하지 않다(참조할 수 없다)는 것이다.

단, let keyword를 사용하여 변수를 생성하면 블록 레벨 스코프를 사용할 수 있다.

var x = 0;
{
  var x = 1;
  console.log(x); // 1
}
console.log(x);   // 1

let y = 0;
{
  let y = 1;
  console.log(y); // 1
}
console.log(y);   // 0

2. 변수에 따른 특성

변수재선언 여부재할당 여부변수의 범위
varOOfunction {}, 함수 내에서 선언시 함수 내에서만 사용
letXO{}
constXX{}

3. 렉시컬 스코프

렉시컬 스코프는 함수를 어디서 호출하는지가 아니라 어디에 선언하였는지에 따라 결정된다. 자바스크립트는 렉시컬 스코프를 따르므로 함수를 선언한 시점에 상위 스코프가 결정된다. 함수를 어디에서 호출하였는지는 스코프 결정에 아무런 의미를 주지 않는다.

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // 1
bar(); // 1

4. this의 명시적 바인딩

apply

apply() 메소드를 호출하는 주체는 함수이며 apply() 메소드는 this를 특정 객체에 바인딩할 뿐 본질적인 기능은 함수 호출이다.

func.apply(thisArg, [argsArray])

// thisArg: 함수 내부의 this에 바인딩할 객체
// argsArray: 함수에 전달할 argument의 배열

arguments 객체와 같은 유사 배열 객체에 배열 메소드를 사용할 때 아래와 같이 사용된다.

function convertArgsToArray() {
  console.log(arguments);

  // arguments 객체를 배열로 변환
  // slice: 배열의 특정 부분에 대한 복사본을 생성한다.
  var arr = Array.prototype.slice.apply(arguments); // arguments.slice
  // var arr = [].slice.apply(arguments);

  console.log(arr);
  return arr;
}

convertArgsToArray(1, 2, 3);  // [1,2,3]

call

apply()와 기능은 같지만 apply()의 두번째 인자에서 배열 형태로 넘긴 것을 각각 하나의 인자로 넘긴다.

Person.apply(foo, [1, 2, 3]);
Person.call(foo, 1, 2, 3);

콜백함수 내부의 this를 콜백함수를 호출하는 함수 내부의 this와 일치시켜줄 때 아래와 같이 사용된다.

function Person(name) {
  this.name = name;
}

Person.prototype.doSomething = function (callback) {
  if (typeof callback == 'function') {
    callback.call(this); // call을 사용하지 않으면 foo에서 this는 window가 된다.
  }
};

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

var p = new Person('Lee');
p.doSomething(foo);  // 'Lee'

bind

인자로 전달한 this가 바인딩된 새로운 함수를 리턴한다.

let user = {
  firstName: "John"
};

function func() {
  console.log(this.firstName);
}

let funcUser = func.bind(user);
funcUser(); // John

한번 bind를 적용하면 bind를 사용하여 다시 정의할 수 없다.

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

f = f.bind( {name: "John"} ).bind( {name: "Ann" } );

f(); // John

스코프,this편을 마무리하며

  1. 그냥 사용하거나 일반 함수 안에서 쓰면 window, strict mode 에서 일반함수 내에서 쓰면 undefined
  2. 오브젝트 내 함수(메소드)안에서 쓰면 함수를 갖고 있는 오브젝트를 의미
  3. 이벤트리스너안에서는 e.currentTarget

참고
자바스크립트의 기본
함수 바인딩

profile
작은 성취들이 모여 큰 결과를 만든다고 믿으며, 꾸준함을 바탕으로 개발 역량을 키워가고 있습니다

0개의 댓글