JavaScript의 this 지향 및 바인딩 상세 정보
8900 단어 JavaScriptthis가리키다바인딩
this가 가리키는 유형
자바스크립트를 처음 배울 때,this는 항상 사람을 가장 현혹시킨다. 자바스크립트에서this의 지향을 어떻게 확정해야 하는지 살펴본다.
this는 함수가 호출될 때 확정되며, 그 지향은 함수가 호출되는 곳에 달려 있으며, 설명된 곳에 달려 있지 않습니다. (화살표 함수를 제외하고)함수가 호출될 때 실행 상하문을 만듭니다. 함수가 어디서 호출되는지 (호출 창고), 함수의 호출 방식, 전송된 매개 변수 등 정보를 포함합니다.this는 이 기록의 속성입니다. 함수가 실행되는 과정에서 사용됩니다.
this는 함수의 지향점에 다음과 같은 몇 가지 장면이 있습니다.
1.new 바인딩
함수가 구조 함수로 new 호출을 사용할 때,this는 새로 만든 구조 함수의 실례를 연결합니다.
function Foo() {
console.log(this)
}
var bar = new Foo() // : Foo ,this bar
실제로 new를 사용하여 구조 함수를 호출할 때 다음 동작을 순서대로 실행합니다.콜,apply,bind를 통해 함수 귀속된this를 수정하여 우리가 지정한 대상이 될 수 있습니다.이 방법의 첫 번째 매개 변수를 통해 우리는this를 현저하게 연결할 수 있다.
function foo(name, price) {
this.name = name
this.price = price
}
function Food(category, name, price) {
foo.call(this, name, price) // call
// foo.apply(this, [name, price]) // apply
this.category = category
}
new Food(' ', ' ', '5 ')
// : {name: " ", price: "5 ", category: " "}
call과 apply의 차이는call 방법은 매개 변수 목록을 받아들이고, apply 방법은 매개 변수 그룹을 받아들인다는 것이다.
func.call(thisArg, arg1, arg2, ...) // call
func.apply(thisArg, [arg1, arg2, ...]) // apply
bind 방법은this를 주어진 값으로 설정하고 새로운 함수를 되돌려주며, 새로운 함수를 호출할 때, 주어진 매개 변수 목록을 원 함수의 매개 변수 서열의 앞부분으로 하는 것이다.
func.bind(thisArg[, arg1[, arg2[, ...]]]) // bind
예:
var food = {
name: ' ',
price: '5 ',
getPrice: function (place) {
console.log(place + this.price)
},
}
food.getPrice('KFC ') // : "KFC 5 "
var getPrice1 = food.getPrice.bind({ name: ' ', price: '7 ' }, ' ')
getPrice1() // : " 7 "
bind의 원리에 관해서 우리는 apply 방법을 사용하여 스스로 bind를 실현할 수 있다.
// ES5
Function.prototype.bind =
Function.prototype.bind ||
function () {
var self = this
var rest1 = Array.prototype.slice.call(arguments)
var context = rest1.shift()
return function () {
var rest2 = Array.prototype.slice.call(arguments)
return self.apply(context, rest1.concat(rest2))
}
}
// ES6
Function.prototype.bind =
Function.prototype.bind ||
function (...rest1) {
const self = this
const context = rest1.shift()
return function (...rest2) {
return self.apply(context, [...rest1, ...rest2])
}
}
ES6 방식은 일부 ES6의 지식, 예를 들어rest 매개 변수, 수조 해체를 사용했다.주의:null이나undefined를this의 귀속 대상으로call,apply,bind에 전송하면 이 값은 호출할 때 무시됩니다. 실제 적용되는 것은 기본 귀속 규칙입니다.
var a = 'hello'
function foo() {
console.log(this.a)
}
foo.call(null) // : "hello"
3. 암시적 귀속함수가 어떤 상하문 대상에서 호출되는지, 만약 그렇다면this가 귀속된 것은 그 상하문 대상이다.
var a = 'hello'
var obj = {
a: 'world',
foo: function () {
console.log(this.a)
},
}
obj.foo() // : "world"
위 코드에서foo방법은 대상의 속성으로 호출된 것입니다. 그러면 이때foo방법이 실행될 때,this는obj대상을 가리킵니다.즉, 이때this는 이 방법을 호출하는 대상을 가리키고 여러 개의 대상을 끼워 넣으면 마지막으로 이 방법을 호출하는 대상을 가리킨다.
var a = 'hello'
var obj = {
a: 'world',
b: {
a: 'China',
foo: function () {
console.log(this.a)
},
},
}
obj.b.foo() // : "China"
마지막 대상은obj의 b입니다. 그러면 이때foo방법이 실행될 때 그 중this가 가리키는 것은 b대상입니다.4. 기본 바인딩
함수가 독립적으로 호출되고 어떠한 수식도 없는 함수 인용을 직접 사용하여 호출하는 것도 상기 몇 가지 귀속 경로 이외의 방식이다.비엄격한 모드에서this는 전역 대상(브라우저 아래는winodw,node 환경은global), 엄격한 모드에서this는undefined로 귀속됩니다(엄격한 모드에서this가 전역 대상을 가리키는 것을 허용하지 않기 때문).
var a = 'hello'
function foo() {
var a = 'world'
console.log(this.a)
console.log(this)
}
foo() // window.foo()
// : "hello"
// : Window
위 코드에서 변수 a는 전역 작용역에 성명되어 전역 대상 윈도우의 동명 속성이 됩니다.함수foo가 실행될 때,this는 전역 대상을 가리키기 때문에 출력된 a는 전역 대상의 속성입니다.참고:
var a = 'hello'
var obj = {
a: 'world',
foo: function () {
console.log(this.a)
},
}
var bar = obj.foo
bar() // : "hello"
이때 bar 함수, 즉obj의foo방법은 왜 전역 대상을 가리키는가. bar 방법은 이때 함수로 독립적으로 호출되기 때문에 이 장면은 기본 귀속에 속하고 은식 귀속이 아니다.이러한 상황은 메서드를 콜백 함수로 사용하는 장면과 유사합니다.
var a = 'hello'
var obj = {
a: 'world',
foo: function () {
console.log(this.a)
},
}
function func(fn) {
fn()
}
func(obj.foo) // : "hello"
매개 변수 전달도 사실상 은밀한 값이다. 단지 여기obj에 불과하다.foo 방법은 은식부치에 의해 함수func의 형삼 fn에 부여되었고 이전의 상황은 자신이 부여한 것으로 두 가지 상황은 실제로 유사하다.이런 장면에서 우리가 비교적 많이 만나는 것은 set Timeout과 set Interval이다. 만약에 리셋 함수가 화살표 함수가 아니라면this가 가리키는 것은 전역 대상이다.사실 우리는 기본 귀속을 은식 귀속의 특수한 상황으로 여길 수 있다. 예를 들어 위의bar (), 우리는 윈도우를 사용하는 것으로 여길 수 있다.bar () 방식으로 호출되었습니다. 이때 bar의this는 은식으로 연결된 상황에 따라 윈도우를 가리킵니다.
this 귀속 우선 순위
this는 여러 개의 사용 장면이 존재한다. 그러면 여러 장면이 동시에 나타날 때this는 도대체 어떻게 가리켜야 하는가.여기에 우선순위의 개념이 존재한다.this는 우선순위에 따라 지향을 확정한다.우선 순위: new 바인딩 > 표시 바인딩 > 스텔스 바인딩 > 기본 바인딩
그래서this의 판단 순서:
화살표 함수는 선언된 곳에 따라this를 결정합니다. 이것은 ES6의 지식점입니다.
화살표 함수의this 귀속은call,apply,bind를 통해 수정될 수 없으며, 화살표 함수에 구조 함수constructor가 없기 때문에 new 호출을 사용할 수 없습니다. 즉, 구조 함수로 사용할 수 없습니다. 그렇지 않으면 오류가 발생합니다.
var a = 'hello'
var obj = {
a: 'world',
foo: () => {
console.log(this.a)
},
}
obj.foo() // : "hello"
ECMAScript 표준에서 화살표 함수에 대한 설명을 볼 수 있습니다.원문:
An Arrow Function does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function.
번역:
화살표 함수는arguments, 슈퍼,this 또는 new가 아닙니다.target은 로컬 귀속을 정의합니다.화살표 함수에서arguments, 슈퍼,this 또는 new.target의 모든 인용은 현재 있는 어법 작용 영역의 귀속으로 해석됩니다.일반적으로 이것은 화살표 함수가 있는 함수 작용역입니다.
―ECMAScript Language Specification - Arrow Function | ECMA 표준 - 화살표 함수
this의 작은 연습
작은 연습으로 실전을 해보세요.
var a = 20
var obj = {
a: 40,
foo: () => {
console.log(this.a)
function func() {
this.a = 60
console.log(this.a)
}
func.prototype.a = 50
return func
},
}
var bar = obj.foo() // : 20
bar() // : 60
new bar() // : 60
조금만 설명해 주세요.1) var a = 20 이 문장은 전역 변수 윈도우에 속성 a를 만들고 값을 20으로 부여합니다.
2) 우선 obj를 실행합니다.foo(), 이것은 화살표 함수입니다. 화살표 함수는 새로운 함수 작용역을 만들지 않고 문장 외부의 작용역을 그대로 사용합니다. 따라서obj.foo()가 실행될 때 화살표 함수 중this는 전역 윈도우입니다. 먼저 윈도우의 속성 a의 값 20을 출력하고 화살표 함수는 원형에 50의 속성 a의 함수 대상인 func를 bar에 되돌려줍니다.
3) 계속 실행하는 것은 bar (), 여기 실행하는 것은 방금 화살표 함수가 되돌아온 패키지 func입니다. 그 내부의this는 윈도우를 가리키기 때문에this.a 윈도우를 수정했습니다.a의 값은 60이고 출력합니다.
4) 그리고 실행하는 것은 newbar()입니다. 이전의 설명에 의하면 new 조작부호는func 함수에서func 원형을 계승한 실례 대상을 만들고this로 가리키며this.a = 60은 실례 대상에 속성 a를 만들었고 이후 인쇄에서 실례에서 속성 a를 찾았기 때문에 대상의 원형을 계속 찾지 않기 때문에 세 번째 60을 출력합니다.
만약 상기 예의 화살표 함수를 일반 함수로 바꾸면 결과는 어떻게 될까요?
var a = 20
var obj = {
a: 40,
foo: function () {
console.log(this.a)
function func() {
this.a = 60
console.log(this.a)
}
func.prototype.a = 50
return func
},
}
var bar = obj.foo() // : 40
bar() // : 60
new bar() // : 60
이 예는 상세하게 설명하지 않는다.만약 위의 두 가지 예를 원리를 이해한다면 기본적으로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에 따라 라이센스가 부여됩니다.