자 바스 크 립 트 가 조금씩 시 리 즈 를 돌파 하 는 this 는 무엇 입 니까?
12655 단어 JavaScriptthis
아마도 당신 은 다른 대상 을 대상 으로 하 는 프로 그래 밍 언어
this를 본 적 이 있 을 것 입 니 다.또한 그것 이 특정한 구조 기(constructor)가 만 든 대상 을 가리 키 는 것 도 알 고 있 습 니 다.그러나 사실상 자 바스 크 립 트 에서this대표 하 는 것 은 그 세 워 진 대상 만 이 아니다.먼저 ECMAScript 표준 규범 이 this 에 대한 정 의 를 살 펴 보 겠 습 니 다.
「The this keyword evaluates to the value of the ThisBinding of the current execution context.」
"this 라 는 키 워드 는 현재 실행 중인 컨 텍스트 의 ThisBinding 을 대표 합 니 다."
그리고 MDN 이 this 에 대한 정 의 를 살 펴 보 겠 습 니 다.
「In most cases, the value of this is determined by how a function is called.」
"대부분의 경우 this 의 값 은 함수 호출 방식 에 달 려 있 습 니 다."
자,위 두 줄 이 알 아 볼 수 있다 면 더 이상 내 려 다 보지 않 아 도 됩 니 다.축하합니다!
...그 럴 리 가 없 을 것 같 아 요.적어도 이 두 줄 만 봐 도 모 르 겠 어 요.
먼저 예 를 들 어 봅 시다.
var getGender = function() {
return people1.gender;
};
var people1 = {
gender: 'female',
getGender: getGender
};
var people2 = {
gender: 'male',
getGender: getGender
};
console.log(people1.getGender()); // female
console.log(people2.getGender()); // femalewhat?왜 people 2 가 변 했 지?내 가 원 하 는 결과 가 아니 잖 아.왜 지?getGender()되 돌아 가기(return)로 죽은people1.gender관 계 를 썼 기 때문에 결 과 는 당연히'female'이다.그럼 우리 가
getGender를 조금 만 고치 면:
var getGender = function() {
return this.gender;
};이 럴 때 는 각각female과male두 가지 결 과 를 얻 을 수 있 을 것 이다.그래서 앞에서 말 한 중점 으로 돌아 가면 이 예 에서 알 수 있 듯 이
people1와people2의getGender방법 은 모두 같은 getGender function 을 참조 하지만 호출 대상 이 다 르 기 때문에 실 행 된 결과 도 다르다.지금 우 리 는 첫 번 째 중점 을 알 게 되 었 습 니 다.**this 는 실제 함수 가 호출 될 때 발생 하 는 바 인 딩 입 니 다.그것 이 무엇 을 가리 키 는 지 는 함수 의 호출 방식 에 달 려 있 습 니 다.**this 를 어떻게 구분 합 니까?
this 도대체 누구 야
위의 예 를 보 니 아직도 좀 아 는 것 같 지 않 습 니까?그럼 다음은 서로 다른 호출 방식 이 this 값 에 미 치 는 영향 을 살 펴 보 겠 습 니 다.
상황 1:전역 대상&일반 함수 호출
전역 환경 에서 this 는 전역 대상 을 가리 키 며 브 라 우 저 에서 window 대상 입 니 다.아래 의 예제 에서 엄격 한 모델 이 든 아니 든 this 는 전체 대상 을 가리킨다.
var x = 1
console.log(this.x) // 1
console.log(this.x === x) // true
console.log(this === window) // true만약 에 일반 함수 가 전체 환경 에서 호출 된다 면 엄격 하지 않 은 모드 에서 일반 함수 에서 this 도 전체 대상 을 가리킨다.엄격 한 모드 라면 this 는 undefined 가 될 것 입 니 다.ES5 는 자 바스 크 립 트 가 더 제한 적 인 환경 에서 작 동 하도록 엄격 한 모드 를 추 가 했 고엄격 한 패턴보안 위험 을 없 애기 위해 this 키워드 가 전체 대상 을 가리 키 는 것 을 금지 했다.
var x = 1
function fn() {
console.log(this); // Window
console.log(this.x); // 1
}
fn(); 엄격 한 모드 사용 후:
"use strict" //
var x = 1
function fn() {
console.log(this); // undefined
console.log(this.x); // "Cannot read property 'x' of undefined", this undefined
}
fn(); 상황 2:대상 방법의 호출대상 에 있 는 값 이 원생 값 이 라면(primitive type;예 를 들 어 문자열,수치,불 값)은 새로 만 든 것 을'속성(property)'이 라 고 부 릅 니 다.대상 안의 값 이 함수(function)라면 우 리 는 이 새로 만 든 것 을'방법(method)'이 라 고 부 를 것 이다.
함수 가 대상 의 한 방법 일 때,대상 의 한 방법 으로 호출 될 때,함수 중의 this 는 이 상위 대상 을 가리킨다.
var x = 1
var obj = {
x: 2,
fn: function() {
console.log(this);
console.log(this.x);
}
}
obj.fn()
// obj.fn() ;
// Object {x: 2, fn: function}
// 2
var a = obj.fn
a()
// a() :
// Window
// 1위의 예 에서 obj.fn()을 직접 실행 하고 이 함 수 를 호출 하 는 상위 대상 은 obj 이기 때문에 this 는 obj 를 가리 키 며 this.x 의 값 은 2 입 니 다.그 후에 우 리 는 fn 방법 을 먼저 변수 a 에 할당 하고 a 는 전체 환경 에서 실 행 됩 니 다.그래서 이때 this 는 전체 대상 Window 를 가리 키 고 this.x 를 1 로 가 져 옵 니 다.함수 가 여러 개의 대상 에 끼 워 넣 어 호출 되면 this 가 무엇 을 가리 키 는 지 다시 한 번 보 겠 습 니 다.
var x = 1
var obj = {
x: 2,
y: {
x: 3,
fn: function() {
console.log(this); // Object {x: 3, fn: function}
console.log(this.x); // 3
}
}
}
obj.y.fn(); 왜 결 과 는 2 가 아 닙 니까?이런 상황 에서 한 마디 를 기억 하기 때 문 입 니 다.this 는 함 수 를 직접 호출 하 는 상위 대상,즉 y 를 가리 키 기 때 문 입 니 다.위의 예 는 실제 적 으로 다음 코드 를 실행 합 니 다.
var y = {
x: 3,
fn: function() {
console.log(this); // Object {x: 3, fn: function}
console.log(this.x); // 3
}
}
var x = 1
var obj = {
x: 2,
y: y
}
obj.y.fn(); 대상 은 끼 워 넣 을 수 있 고 함수 도 끼 워 넣 을 수 있 습 니 다.함수 가 끼 워 넣 으 면 this 가 달라 질 까요?우 리 는 아래 코드 를 통 해 토론 합 시다.
var obj = {
y: function() {
console.log(this === obj); // true
console.log(this); // Object {y: function}
fn();
function fn() {
console.log(this === obj); // false
console.log(this); // Window
}
}
}
obj.y(); 함수 y 에서 this 는 이전 대상 obj 를 호출 하 는 것 을 가리 키 며 문제 가 없습니다.그러나 내장 함수 fn 에서 this 는 obj 를 가리 키 지 않 습 니 다.끼 워 넣 은 함 수 는 호출 된 함수 에서 this 를 계승 하지 않 습 니 다.끼 워 넣 은 함 수 를 함수 로 호출 할 때 this 값 은 엄격 하지 않 은 모드 에서 전체 대상 을 가리 키 고 엄격 한 모드 에 서 는 undefined 이기 때문에 위의 예 는 실제 적 으로 다음 코드 를 실행 합 니 다.
function fn() {
console.log(this === obj); // false
console.log(this); // Window
}
var obj = {
y: function() {
console.log(this === obj); // true
console.log(this); // Object {y: function}
fn();
}
}
obj.y(); 상황 3:구조 함수 로 호출우 리 는 new 키 워드 를 사용 하여 구조 함 수 를 통 해 인 스 턴 스 대상 을 만 들 수 있 습 니 다.이때 this 는 이 새로운 대상 을 가리킨다.
var x = 1;
function Fn() {
this.x = 2;
console.log(this); // Fn {x: 2}
}
var obj = new Fn(); // obj Fn(..) this
console.log(obj.x) // 2new를 사용 하여 호출Fn(..)할 때 새 대상 을 만 들 고(obj)를Fn(..)호출 중인 this 에 연결 합 니 다.또한,구조 함수 가 비 인용 형식(string,number,boolean,null,undefined)을 되 돌려 주면 this 는 여전히 실례 화 된 새로운 대상 을 가리 키 고 있 습 니 다.
var x = 1
function Fn() {
this.x = 2
return {
x: 3
}
}
var a = new Fn()
console.log(a.x) // 3Fn()반환(return)은 하나의 대상(참조 형식)이기 때문에 this 는 이 return 의 대상 을 가리 키 기 때 문 입 니 다.return 이 비 인용 형식의 값 이 라면?
var x = 1
function Fn() {
this.x = 2
return 3
}
var a = new Fn()
console.log(a.x) // 2상황 4:콜 과 apply 방법 호출this 의 방향 을 바 꾸 고 싶다 면 콜 이나 apply 방법 을 사용 하 십시오.그들의 첫 번 째 매개 변 수 는 모두 지 정 된 함수 가 실 행 될 때 그 중의
this가 가리 키 는 것 이다.첫 번 째 매개 변수 가 전송 되 지 않 거나 null,undefined 를 전송 하지 않 으 면 기본 this 는 전체 대상(비 엄격 모드)이나 undefined(엄격 모드)를 가리 킵 니 다.
var x = 1;
var obj = {
x: 2
}
function fn() {
console.log(this);
console.log(this.x);
}
fn.call(obj)
// Object {x: 2}
// 2
fn.apply(obj)
// Object {x: 2}
// 2
fn.call()
// Window
// 1
fn.apply(null)
// Window
// 1
fn.call(undefined)
// Window
// 1call 과 apply 를 사용 할 때 this 에 전 달 된 대상 이 아니라면 자바 스 크 립 트 는 관련 구조 함 수 를 사용 하여 대상 으로 전환 합 니 다.예 를 들 어 number 형식 은new Number()작업 을 합 니 다.예 를 들 어 string 형식 은new String()작업 을 합 니 다.예 를 들 어 boolean 형식 은 new Boolean()작업 을 합 니 다.
function fn() {
console.log(Object.prototype.toString.call(this))
}
fn.call('love') // [object String]
fn.apply(1) // [object Number]
fn.call(true) // [object Boolean]call 과 apply 의 차 이 는 call 의 두 번 째 및 후속 매개 변 수 는 하나의 매개 변수 목록 이 고 apply 의 두 번 째 매개 변 수 는 배열 이다.매개 변수 목록 과 매개 변수 배열 은 함수 의 매개 변수 로 실 행 됩 니 다.
var x = 1
var obj = {
x: 2
}
function Sum(y, z) {
console.log(this.x + y + z)
}
Sum.call(obj, 3, 4) // 9
Sum.apply(obj, [3, 4]) // 9상황 5:bind 방법 호출f.bind(someObject)를 호출 하면 f 와 같은 함수 체 와 작용 역 을 가 진 함 수 를 만 듭 니 다.그러나 이 새 함수 에서 새 함수 의 this 는 bind 가 들 어 오 는 첫 번 째 매개 변 수 를 영구적 으로 가리 키 며,이 함수 가 어떻게 호출 되 든 간 에.
var x = 1
var obj1 = {
x: 2
};
var obj2 = {
x: 3
};
function fn() {
console.log(this);
console.log(this.x);
};
var a = fn.bind(obj1);
var b = a.bind(obj2);
fn();
// Window
// 1
a();
// Object {x: 2}
// 2
b();
// Object {x: 2}
// 2
a.call(obj2);
// Object {x: 2}
// 2위의 예 에서 함수 a 에 this 의 방향 을 다시 지정 하려 고 시 도 했 지만 첫 번 째 bid 가 들 어 오 는 대상 을 가리 키 고 있 습 니 다.call 이나 apply 방법 을 사용 하 더 라 도 이 사실 을 바 꿀 수 없습니다.즉,영구적 으로 bid 가 들 어 오 는 첫 번 째 매개 변 수 를 가리 키 는 것 입 니 다.상황 6:화살표 함수 에서 this 지향
특히 ES6 부터 화살표 함수 가 추 가 돼 MDN 에서 화살표 함수 에 대한 설명 을 살 펴 봤 다.
An arrow function expression has a shorter syntax than a function expression and does notbind its own
this , arguments , super , or new.target . Arrow functions are always anonymous. These function expressions are best suited for non-method functions, and they cannot be used as constructors.화살표 함수 가 자신의
this바 인 딩 이 없다 는 것 을 분명히 설명 했다.화살표 함수 에 사용 되 는this은 그 함수 나 함수 표현 식 에 직접 포 함 된this입 니 다.앞의 상황 에서 2 중 함수 내장 함수 의 예 에서 포 함 된 함 수 는 상층 함수 의 this 를 계승 하지 않 습 니 다.화살표 함 수 를 사용 하면 어떤 변화 가 발생 합 니까?
var obj = {
y: function() {
console.log(this === obj); // true
console.log(this); // Object {y: function}
var fn = () => {
console.log(this === obj); // true
console.log(this); // Object {y: function}
}
fn();
}
}
obj.y() 일반 함수 와 달리 화살표 함수 의 this 는 obj 를 가리 키 고 있 습 니 다.이것 은 이전 함수 에서 this 를 계승 하기 때 문 입 니 다.화살표 함수 가 this 의 방향 을 수정 한 것 으로 이해 할 수 있 습 니 다.그래서 화살표 함수 의 this 는 호출 할 때 결정 되 는 것 이 아니 라 정의 할 때 있 는 대상 이 바로 this 입 니 다.다시 말 하면 화살표 함수 의 this 는 외층 에 함수 가 있 는 지,있 으 면 외층 함수 의 this 는 내부 화살표 함수 의 this 이 고 없 으 면 this 는 window 이다.
var obj = {
y: () => {
console.log(this === obj); // false
console.log(this); // Window
var fn = () => {
console.log(this === obj); // false
console.log(this); // Window
}
fn();
}
}
obj.y() 위의 예 에서 두 개의 화살표 함수 가 존재 하지만,사실 this 는 가장 바깥쪽 의 화살표 함수 에 달 려 있 습 니 다.obj 는 함수 가 아 닌 대상 이기 때문에 this 는 Window 전역 대상 을 가리 키 고 있 습 니 다.bind 와 마찬가지 로 화살표 함수 도 매우 완고 합 니 다.우 리 는 call 과 apply 를 통 해 this 의 방향 을 바 꿀 수 없습니다.즉,들 어 오 는 첫 번 째 매개 변 수 는 무시 되 었 습 니 다.
var x = 1
var obj = {
x: 2
}
var a = () => {
console.log(this.x)
console.log(this)
}
a.call(obj)
// 1
// Window
a.apply(obj)
// 1
// Window 위의 문자 묘사 가 너무 많 으 면 약간 건조 할 수 있 습 니 다.그러면 아래 의 이 절차 도 를 보 세 요.저 는 이 그림 이 잘 정리 되 었 다 고 생각 합 니 다.그림 속 의 절 차 는 하나의 규칙 에 만 초점 을 두 고 있 습 니 다.
작은 매듭
이 글 은 this 가 가리 키 는 몇 가지 상황 을 소개 하 였 으 며,서로 다른 운행 환경 과 호출 방식 이 this 에 영향 을 미 칠 수 있다.전체적으로 말 하면 함수 this 의 지향 은 현재 이 함 수 를 호출 하 는 대상,즉 실행 시의 대상 에 달 려 있다.이 절 에서 당신 은 파악 해 야 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
기초 정리 - 1문자 (String) 숫자 (Number) 불린 (Boolean) null undefined 심볼 (Symbol) 큰정수 (BigInt) 따옴표로 묶어 있어야 함 Not-A-Number - 숫자 데이터 / 숫자로 표...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.