JavaScript의 this 키워드는 초보자와 숙련된 개발자 모두를 당황하게 만드는 기본 개념입니다. 그 동적 특성을 완전히 이해하지 않으면 예상치 못한 동작이 발생할 수 있습니다. 이 종합 가이드는 다양한 맥락, 뉘앙스, 모범 사례를 탐구하고 예시와 도전적인 문제를 통해 이해를 확고히 하여 이에 대한 신비를 없애는 것을 목표로 합니다.
자바스크립트에서 this는 현재 코드가 실행되는 객체를 가리키는 키워드입니다. this가 정적으로 바인딩되는 다른 프로그래밍 언어와 달리 JavaScript의 this는 함수 호출 방식에 따라 동적으로 결정됩니다.
함수 내부에 있지 않은 경우 전역 개체를 참조합니다.
예
console.log(this === window); // true (in browser) console.log(this === global); // true (in Node.js)
참고: 엄격 모드('use strict';)에서는 전역 컨텍스트에서 this가 전역 개체로 유지됩니다.
일반 함수에서는 함수가 어떻게 호출되는지에 따라 결정됩니다.
예:
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"
화살표 함수에는 어휘 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)
new 키워드를 사용하여 함수를 생성자로 사용하는 경우 새로 생성된 인스턴스를 나타냅니다.
console.log(this === window); // true (in browser) console.log(this === global); // true (in Node.js)
중요 사항:
• new가 사용되지 않으면 전역 객체를 참조하거나 엄격 모드에서 정의되지 않을 수 있습니다.
• 생성자는 일반적으로 일반 함수와 구별하기 위해 첫 글자를 대문자로 표시합니다.
이벤트 핸들러에서는 이벤트를 받은 요소를 의미합니다.
예
function showThis() { console.log(this); } showThis(); // Window object (in browser) or global (in Node.js)
JavaScript는 이 값을 명시적으로 설정하는 방법을 제공합니다.
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"
const person = { name: 'Charlie', greet: () => { console.log(`Hello, I'm ${this.name}`); } }; person.greet(); // "Hello, I'm undefined" (or global name if defined)
사용 사례:
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)
메서드를 콜백으로 전달하면 원래 컨텍스트가 손실될 수 있습니다.
문제
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 });
화살표 함수에는 자체 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"
전역 개체에 실수로 속성을 설정하면 버그가 발생할 수 있습니다.
문제
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."
중첩된 함수에서 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
프로토타입 사용시 인스턴스를 의미합니다.
console.log(this === window); // true (in browser) console.log(this === global); // true (in Node.js)
JavaScript의 this 키워드는 올바르게 이해하면 코딩 능력을 크게 향상시킬 수 있는 다재다능하고 강력한 기능입니다.
이에 대한 이해를 확고히 하려면 다음과 같은 어려운 문제를 해결해 보세요. 각 문제는 JavaScript에서 this 키워드의 다양한 측면과 극단적인 경우를 테스트하도록 설계되었습니다. 결국 해결책.
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"
function greet() { console.log(`Hello, I'm ${this.name}`); } const person = { name: 'Bob' }; greet.call(person); // "Hello, I'm Bob"
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)
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 });
function greet(greeting) { console.log(`${greeting}, I'm ${this.name}`); } const person = { name: 'Eve' }; greet.call(person, 'Hello'); // "Hello, I'm Eve"
getName이 변수에 할당되고 개체 컨텍스트 없이 호출되면 기본값은 전역 개체입니다. 비엄격 모드에서 this.name은 'Global'인 전역 이름을 나타냅니다. 엄격 모드에서는 정의되지 않아 오류가 발생합니다.
greet.apply(person, ['Hi']); // "Hi, I'm Eve"
화살표 함수에는 자체 this가 없습니다. 그들은 그것을 주변 범위로부터 상속받습니다. 이 경우 주변 범위는 전역 컨텍스트이며 this.name은 'Global'입니다.
const boundGreet = greet.bind(person); boundGreet('Hey'); // "Hey, I'm Eve"
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."
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"
화살표 함수 getModel은 새로 생성된 자동차 인스턴스를 참조하는 생성자에서 이를 상속합니다.
const obj = { name: 'Object', getName: function() { return this.name; } }; const getName = obj.getName; console.log(getName()); // undefined or global name
일반 함수를 사용하는 이벤트 핸들러에서는 이벤트를 수신한 DOM 요소, 즉 버튼을 의미합니다. 버튼에는 name 속성이 없으므로 this.name은 정의되지 않습니다.
console.log(this === window); // true (in browser) console.log(this === global); // true (in Node.js)
function showThis() { console.log(this); } showThis(); // Window object (in browser) or global (in Node.js)
Promise 생성자 내에서 이는 전역 개체를 참조합니다(또는 엄격 모드에서는 정의되지 않음). 따라서 this.value는 정의되지 않습니다(또는 엄격 모드에서는 오류가 발생합니다).
const person = { name: 'Alice', greet: function() { console.log(`Hello, I'm ${this.name}`); } }; person.greet(); // "Hello, I'm Alice"
곱하기 함수는 첫 번째 인수 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"
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!