> 웹 프론트엔드 > JS 튜토리얼 > JavaScript에서 &#this&# 키워드 익히기: 다시는 뒤돌아보지 마세요

JavaScript에서 &#this&# 키워드 익히기: 다시는 뒤돌아보지 마세요

Susan Sarandon
풀어 주다: 2025-01-06 06:59:40
원래의
1027명이 탐색했습니다.

Mastering the

JavaScript의 this 키워드는 초보자와 숙련된 개발자 모두를 당황하게 만드는 기본 개념입니다. 그 동적 특성을 완전히 이해하지 않으면 예상치 못한 동작이 발생할 수 있습니다. 이 종합 가이드는 다양한 맥락, 뉘앙스, 모범 사례를 탐구하고 예시와 도전적인 문제를 통해 이해를 확고히 하여 이에 대한 신비를 없애는 것을 목표로 합니다.

이에 대한 소개

자바스크립트에서 this는 현재 코드가 실행되는 객체를 가리키는 키워드입니다. this가 정적으로 바인딩되는 다른 프로그래밍 언어와 달리 JavaScript의 this는 함수 호출 방식에 따라 동적으로 결정됩니다.

1. 글로벌 컨텍스트

함수 내부에 있지 않은 경우 전역 개체를 참조합니다.

  • 브라우저에서: 전역 개체는 창입니다.
  • Node.js에서: 전역 객체는 전역입니다.


console.log(this === window); // true (in browser)
console.log(this === global); // true (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

참고: 엄격 모드('use strict';)에서는 전역 컨텍스트에서 this가 전역 개체로 유지됩니다.

2. 기능 컨텍스트

I. 일반 기능

일반 함수에서는 함수가 어떻게 호출되는지에 따라 결정됩니다.

  • 기본 바인딩: 컨텍스트 없이 함수가 호출되면 이는 전역 개체를 참조합니다(또는 엄격 모드에서는 정의되지 않음).

예:

function showThis() {
  console.log(this);
}

showThis(); // Window object (in browser) or global (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • 암시적 바인딩: 객체의 메서드로 함수를 호출할 때 해당 객체를 참조합니다.


const person = {
  name: 'Alice',
  greet: function() {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm Alice"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

call, apply 또는 bind를 사용하여 이를 명시적으로 설정할 수 있습니다.

function greet() {
  console.log(`Hello, I'm ${this.name}`);
}

const person = { name: 'Bob' };
greet.call(person); // "Hello, I'm Bob"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

II. 화살표 기능

화살표 함수에는 어휘 this가 있습니다. 즉, 생성 당시 주변 범위에서 이것을 상속합니다.


const person = {
  name: 'Charlie',
  greet: () => {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm undefined" (or global name if defined)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

설명: 화살표 함수에는 자체 this가 없으므로 사람 개체가 아닌 전역 개체를 참조합니다.

화살표 함수의 올바른 사용법:

const person = {
  name: 'Dana',
  greet: function() {
    const inner = () => {
      console.log(`Hello, I'm ${this.name}`);
    };
    inner();
  }
};

person.greet(); // "Hello, I'm Dana"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

어려운 측면: 메소드가 변수에 할당되어 호출되면 의도한 컨텍스트를 잃을 수 있습니다.

const calculator = {
  value: 0,
  add: function(num) {
    this.value += num;
    return this.value;
  }
};

console.log(calculator.add(5)); // 5
console.log(calculator.add(10)); // 15

const addFunction = calculator.add;
console.log(addFunction(5)); // NaN (in non-strict mode, this.value is undefined + 5)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

3. 생성자 함수와 이것

new 키워드를 사용하여 함수를 생성자로 사용하는 경우 새로 생성된 인스턴스를 나타냅니다.

console.log(this === window); // true (in browser)
console.log(this === global); // true (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

중요 사항:
• new가 사용되지 않으면 전역 객체를 참조하거나 엄격 모드에서 정의되지 않을 수 있습니다.
• 생성자는 일반적으로 일반 함수와 구별하기 위해 첫 글자를 대문자로 표시합니다.

4. 이벤트 핸들러의 this

이벤트 핸들러에서는 이벤트를 받은 요소를 의미합니다.


function showThis() {
  console.log(this);
}

showThis(); // Window object (in browser) or global (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

5. 호출, 적용, 바인딩을 통한 명시적 바인딩

JavaScript는 이 값을 명시적으로 설정하는 방법을 제공합니다.

  • call: 이 설정을 첫 번째 인수로 설정한 다음 함수 인수를 사용하여 함수를 호출합니다.
const person = {
  name: 'Alice',
  greet: function() {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm Alice"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • 적용: 호출과 유사하지만 인수를 배열로 허용합니다.
function greet() {
  console.log(`Hello, I'm ${this.name}`);
}

const person = { name: 'Bob' };
greet.call(person); // "Hello, I'm Bob"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사
  • bind: 첫 번째 인수에 바인딩된 새 함수를 반환합니다.
const person = {
  name: 'Charlie',
  greet: () => {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm undefined" (or global name if defined)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

사용 사례:

  • 다른 객체에서 메서드를 빌리는 것.
  • 콜백에서 이것이 일관되게 유지되는지 확인하세요.

6. 수업 중

ES6에서는 생성자 함수와 메서드에 대한 보다 명확한 구문을 제공하는 클래스를 도입했습니다. 클래스 메소드 내에서 이는 인스턴스를 나타냅니다.
예:

const person = {
  name: 'Dana',
  greet: function() {
    const inner = () => {
      console.log(`Hello, I'm ${this.name}`);
    };
    inner();
  }
};

person.greet(); // "Hello, I'm Dana"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

클래스의 화살표 기능:
메서드에 화살표 함수를 사용하여 클래스 컨텍스트에서 이를 상속할 수 있으며 콜백에 유용합니다.

const calculator = {
  value: 0,
  add: function(num) {
    this.value += num;
    return this.value;
  }
};

console.log(calculator.add(5)); // 5
console.log(calculator.add(10)); // 15

const addFunction = calculator.add;
console.log(addFunction(5)); // NaN (in non-strict mode, this.value is undefined + 5)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

일반적인 함정과 모범 사례

I. 이 맥락의 상실

메서드를 콜백으로 전달하면 원래 컨텍스트가 손실될 수 있습니다.
문제

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

const alice = new Person('Alice');
console.log(alice.name); // "Alice"
로그인 후 복사
로그인 후 복사

솔루션
컨텍스트를 보존하려면 바인딩을 사용하세요.

<button>



<p><strong>Arrow Function Caveat:</strong><br>
Using arrow functions in event handlers can lead to this referring to the surrounding scope instead of the event target.<br>
<strong>Example:</strong><br>
</p>

<pre class="brush:php;toolbar:false">button.addEventListener('click', () => {
  console.log(this); // Global object or enclosing scope
});
로그인 후 복사
로그인 후 복사

II. 화살표 기능을 부적절하게 사용하기

화살표 함수에는 자체 this가 없으므로 메서드로 사용할 때 예상치 못한 동작이 발생할 수 있습니다.

문제

function greet(greeting) {
  console.log(`${greeting}, I'm ${this.name}`);
}

const person = { name: 'Eve' };
greet.call(person, 'Hello'); // "Hello, I'm Eve"
로그인 후 복사
로그인 후 복사

솔루션
객체 메서드에는 일반 함수를 사용하세요.

greet.apply(person, ['Hi']); // "Hi, I'm Eve"
로그인 후 복사
로그인 후 복사

III. 글로벌 피하기

전역 개체에 실수로 속성을 설정하면 버그가 발생할 수 있습니다.

문제

const boundGreet = greet.bind(person);
boundGreet('Hey'); // "Hey, I'm Eve"
로그인 후 복사
로그인 후 복사

솔루션
엄격 모드 또는 적절한 바인딩을 사용하세요.

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

const dog = new Animal('Dog');
dog.speak(); // "Dog makes a noise."
로그인 후 복사
로그인 후 복사

고급 개념

I. 중첩된 함수의 경우

중첩된 함수에서 this는 외부 this를 참조하지 않을 수 있습니다. 해결 방법에는 화살표 기능을 사용하거나 이를 변수에 저장하는 것이 포함됩니다.
화살표 기능의 예:

class Person {
  constructor(name) {
    this.name = name;
  }

  greet = () => {
    console.log(`Hello, I'm ${this.name}`);
  }
}

const john = new Person('John');
john.greet(); // "Hello, I'm John"
로그인 후 복사
로그인 후 복사

변수의 예:

const obj = {
  name: 'Object',
  getName: function() {
    return this.name;
  }
};

const getName = obj.getName;
console.log(getName()); // undefined or global name
로그인 후 복사
로그인 후 복사

II. 이것은 프로토타입과 함께

프로토타입 사용시 인스턴스를 의미합니다.

console.log(this === window); // true (in browser)
console.log(this === global); // true (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

결론

JavaScript의 this 키워드는 올바르게 이해하면 코딩 능력을 크게 향상시킬 수 있는 다재다능하고 강력한 기능입니다.


이것을 마스터하기 위한 10가지 까다로운 문제

이에 대한 이해를 확고히 하려면 다음과 같은 어려운 문제를 해결해 보세요. 각 문제는 JavaScript에서 this 키워드의 다양한 측면과 극단적인 경우를 테스트하도록 설계되었습니다. 결국 해결책.

문제 1: 신비한 결과

function showThis() {
  console.log(this);
}

showThis(); // Window object (in browser) or global (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 2: 놀라운 화살표 기능

const person = {
  name: 'Alice',
  greet: function() {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm Alice"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 3: 이를 콜백에 바인딩

function greet() {
  console.log(`Hello, I'm ${this.name}`);
}

const person = { name: 'Bob' };
greet.call(person); // "Hello, I'm Bob"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 4: 바인드를 올바르게 사용하기

const person = {
  name: 'Charlie',
  greet: () => {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm undefined" (or global name if defined)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 5: 생성자 함수에서 발생하는 문제

const person = {
  name: 'Dana',
  greet: function() {
    const inner = () => {
      console.log(`Hello, I'm ${this.name}`);
    };
    inner();
  }
};

person.greet(); // "Hello, I'm Dana"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 6: 이벤트 핸들러 컨텍스트

const calculator = {
  value: 0,
  add: function(num) {
    this.value += num;
    return this.value;
  }
};

console.log(calculator.add(5)); // 5
console.log(calculator.add(10)); // 15

const addFunction = calculator.add;
console.log(addFunction(5)); // NaN (in non-strict mode, this.value is undefined + 5)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 8: Promise의 내용

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

const alice = new Person('Alice');
console.log(alice.name); // "Alice"
로그인 후 복사
로그인 후 복사

문제 9: 바인딩을 사용한 연결

<button>



<p><strong>Arrow Function Caveat:</strong><br>
Using arrow functions in event handlers can lead to this referring to the surrounding scope instead of the event target.<br>
<strong>Example:</strong><br>
</p>

<pre class="brush:php;toolbar:false">button.addEventListener('click', () => {
  console.log(this); // Global object or enclosing scope
});
로그인 후 복사
로그인 후 복사

문제 10: 클래스와 상속에 관한 문제

function greet(greeting) {
  console.log(`${greeting}, I'm ${this.name}`);
}

const person = { name: 'Eve' };
greet.call(person, 'Hello'); // "Hello, I'm Eve"
로그인 후 복사
로그인 후 복사

까다로운 문제에 대한 솔루션

문제 1에 대한 해결책:

getName이 변수에 할당되고 개체 컨텍스트 없이 호출되면 기본값은 전역 개체입니다. 비엄격 모드에서 this.name은 'Global'인 전역 이름을 나타냅니다. 엄격 모드에서는 정의되지 않아 오류가 발생합니다.

greet.apply(person, ['Hi']); // "Hi, I'm Eve"
로그인 후 복사
로그인 후 복사

문제 2에 대한 해결책:

화살표 함수에는 자체 this가 없습니다. 그들은 그것을 주변 범위로부터 상속받습니다. 이 경우 주변 범위는 전역 컨텍스트이며 this.name은 'Global'입니다.

const boundGreet = greet.bind(person);
boundGreet('Hey'); // "Hey, I'm Eve"
로그인 후 복사
로그인 후 복사

문제 3에 대한 해결책:

setInterval 콜백 내에서 이는 전역 개체를 참조합니다(또는 엄격 모드에서는 정의되지 않음). 따라서 this.seconds는 window.seconds를 증가시키거나 엄격 모드에서 오류를 발생시킵니다. 타이머.초는 0으로 유지됩니다.

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

const dog = new Animal('Dog');
dog.speak(); // "Dog makes a noise."
로그인 후 복사
로그인 후 복사

문제 4에 대한 해결책:

retrieveX를 모듈에 바인딩한 후boundGetX()를 호출하면 이를 모듈로 올바르게 설정합니다.

class Person {
  constructor(name) {
    this.name = name;
  }

  greet = () => {
    console.log(`Hello, I'm ${this.name}`);
  }
}

const john = new Person('John');
john.greet(); // "Hello, I'm John"
로그인 후 복사
로그인 후 복사

문제 5에 대한 해결책:

화살표 함수 getModel은 새로 생성된 자동차 인스턴스를 참조하는 생성자에서 이를 상속합니다.

const obj = {
  name: 'Object',
  getName: function() {
    return this.name;
  }
};

const getName = obj.getName;
console.log(getName()); // undefined or global name
로그인 후 복사
로그인 후 복사

문제 6에 대한 해결책:

일반 함수를 사용하는 이벤트 핸들러에서는 이벤트를 수신한 DOM 요소, 즉 버튼을 의미합니다. 버튼에는 name 속성이 없으므로 this.name은 정의되지 않습니다.

console.log(this === window); // true (in browser)
console.log(this === global); // true (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 7에 대한 해결책:

  • 첫번째 console.log(this.name); inside externalFunc는 obj를 참조하므로 'Outer'를 인쇄합니다.
  • 두 번째 console.log(this.name); innerFunc 내부는 전역 객체를 참조하므로 엄격 모드에서는 'Global' 또는 undefound를 인쇄합니다.
function showThis() {
  console.log(this);
}

showThis(); // Window object (in browser) or global (in Node.js)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 8에 대한 해결책:

Promise 생성자 내에서 이는 전역 개체를 참조합니다(또는 엄격 모드에서는 정의되지 않음). 따라서 this.value는 정의되지 않습니다(또는 엄격 모드에서는 오류가 발생합니다).

const person = {
  name: 'Alice',
  greet: function() {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm Alice"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 9에 대한 해결책:

곱하기 함수는 첫 번째 인수 a를 2로 사용하여 바인딩됩니다. double(5)가 호출되면 효과적으로 곱하기(2, 5)를 계산합니다.

function greet() {
  console.log(`Hello, I'm ${this.name}`);
}

const person = { name: 'Bob' };
greet.call(person); // "Hello, I'm Bob"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

문제 10에 대한 해결책:

Dog 클래스의 talk 메소드에서 setTimeout 콜백은 일반 함수입니다. 따라서 콜백 내부의 this는 개 인스턴스가 아닌 전역 개체를 참조합니다. this.name이 '정의되지 않음'이거나 name이 전역적으로 정의되지 않은 경우 오류가 발생합니다.

const person = {
  name: 'Charlie',
  greet: () => {
    console.log(`Hello, I'm ${this.name}`);
  }
};

person.greet(); // "Hello, I'm undefined" (or global name if defined)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이 문제를 해결하려면 화살표 기능을 사용하세요.

const person = {
  name: 'Dana',
  greet: function() {
    const inner = () => {
      console.log(`Hello, I'm ${this.name}`);
    };
    inner();
  }
};

person.greet(); // "Hello, I'm Dana"
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이제 다음 내용이 올바르게 기록됩니다.

const calculator = {
  value: 0,
  add: function(num) {
    this.value += num;
    return this.value;
  }
};

console.log(calculator.add(5)); // 5
console.log(calculator.add(10)); // 15

const addFunction = calculator.add;
console.log(addFunction(5)); // NaN (in non-strict mode, this.value is undefined + 5)
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

위 내용은 JavaScript에서 &#this&# 키워드 익히기: 다시는 뒤돌아보지 마세요의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿