javascript 에서 this 의 작업 원리 및 주의사항
8614 단어 웹 개발
함수 보통 함 축 된 매개 변수 입 니 다.
2. 함수 외 (최상 위 역할 영역 에서): 브 라 우 저 에서 this 전역 대상 을 가리킨다.Node. js 에 서 는 모듈 (module) 내 보 내기 (exports) 를 말 합 니 다.
3. eval () 에 전 달 된 문자열: eval () 이 직접 호출 된다 면 this 현재 대상eval () 이 간접 적 으로 호출 된다 면 this 전체의 대상 을 가리킨다.
이 몇 가지 분류 에 대해 우 리 는 상응하는 테스트 를 했다.
함수 중의 this 함 수 는 기본적으로 JS 에서 호출 될 수 있 는 모든 구 조 를 대표 할 수 있 기 때문에 이것 도 가장 흔히 볼 수 있 는 this 를 사용 합 니 다. 의 장면, 함수 이불 은 다음 과 같은 세 가지 역할 로 나 눌 수 있 습 니 다.
실제 함수 에서 this
실제 함수 에서 this 의 값 은 그것 이 처 한 문맥 의 패턴 에 달 려 있다.
Sloppy 모드: this 전역 대상 (브 라 우 저 에서 window) 을 말 합 니 다.
function sloppyFunc() {
console.log(this === window); // true
}
sloppyFunc();
Strict 모드: this 값 은 undefined 입 니 다.
function strictFunc() {
'
use strict';
console.log(this === undefined); // true
}
strictFunc();
this 함수 의 함 축 된 매개 변수 이기 때문에 값 은 항상 같 습 니 다.하지만 콜 () 이나 apply () 를 사용 하 는 방법 으로 this 의 값 을 표시 할 수 있 습 니 다.
function func(arg1, arg2) {
console.log(this); // 1
console.log(arg1); // 2
console.log(arg2); // 3
}
func.call(1, 2, 3); //(this, arg1, arg2)
func.apply(1, [2, 3]); // (this, arrayWithArgs)
구조 기 중의 this
new 하나의 함 수 를 구조 기로 사용 하 다.new 작업 은 새로운 대상 을 만 들 고 이 대상 을 this 로 통과 합 니 다. 구조 기 에 들어가다.
var savedThis;
function Constr() {
savedThis = this;
}
var inst = new Constr();
console.log(savedThis === inst); // true
JS 중 new 조작의 실현 원 리 는 대략 아래 의 코드 와 같다 (더욱 정확 한 실현 은 여 기 를 보십시오. 이 실현 도 비교적 복잡 합 니 다).
function newOperator(Constr, arrayWithArgs) {
var thisValue = Object.create(Constr.prototype);
Constr.apply(thisValue, arrayWithArgs);
return thisValue;
}
1.3 방법 중의 this
방법 중 this 전통 적 인 대상 언어: this 가리 키 는 수신 자, 즉 이 방법 이 있 는 대상 을 포함한다.
var obj = {
method: function () {
console.log(this === obj); // true
}
}
obj.method();
console.log(this === window); // true
Node. js 에서 당신 은 보통 module 에서 함 수 를 실행 합 니 다.따라서 최고급 역할 영역 은 매우 특별한 모듈 역할 영역 (module scope) 입 니 다.
// `global` (not `window`) refers to global object:
console.log(Math === global.Math); // true
// `this` doesn’t refer to the global object:
console.log(this !== global);// true
// `this` refers to a module’s exports:
console.log(this === module.exports);// true
// Real functions
function sloppyFunc() {
console.log(eval('this') === window); // true
}
sloppyFunc();
function strictFunc() {
'
use strict';
console.log(eval('this') === undefined); // true
}
strictFunc(); // Constructors var savedThis;
function Constr() {
savedThis = eval('this');
}
var inst = new Constr();
console.log(savedThis === inst); // true // Methods
var obj = {
method: function () {
console.log(eval('this') === obj); // true
}
}
obj.method();
4.1 new 를 사용 하 는 것 을 잊 어 버 리 세 요. 만약 당신 이 new 를 사용 하여 구조 기 를 호출 하지 않 았 다 면, 사실은 실제 함 수 를 사용 하고 있 는 것 입 니 다.그래서 this 는 네가 예상 한 값 이 아니다.Sloppy 모드 에서 this 가리 키 는 게 window 예요. 전역 변 수 를 만 들 것 입 니 다:
function Point(x, y) {
this.x = x;
this.y = y;
}
var p = Point(7, 5); // we forgot new!
console.log(p === undefined); // true // Global variables have been created: console.log(x); // 7
console.log(y); // 5
하지만 strict 모드 를 사용한다 면 경 고 를 받 을 수 있 습 니 다 (this = = = undefined):
function Point(x, y) {
'
use strict';
this.x = x;
this.y = y;
}
var p = Point(7, 5); // TypeError: Cannot set property 'x' of undefined
4.2 부적 절 한 사용 방법 만약 에 당신 이 방법의 값 을 직접 얻 으 면 (그것 을 호출 하 는 것 이 아니 라) 이 방법 을 함수 로 사용 하 는 것 입 니 다.하나의 방법 을 하나의 매개 변수 로 함수 나 호출 방법 에 전달 하려 면 이렇게 할 수 있 습 니 다.setTimeout () 과 등록 이벤트 핸들 (event handlers) 이 바로 이런 상황 입 니 다.나 는 callIt () 방법 으로 이 장면 을 모 의 할 것 이다.
/** Similar to setTimeout() and setImmediate() */
function callIt(func) {
func();
}
만약 Sloppy 모드 에서 하나의 방법 을 함수 로 호출 한다 면 * this * 는 전역 대상 을 가리 키 기 때문에 나중에 만 든 것 은 전역 변수 입 니 다.
var counter = {
count: 0, // Sloppy-mode method
inc: function () { this.count++; }
}
callIt(counter.inc); // Didn’t work:
console.log(counter.count); // 0 // Instead, a global variable has been created // (NaN is result of applying ++ to undefined):
console.log(count); // NaN
만약 당신 이 Strict 모드 에서 이렇게 한다 면, this 는 undefined 입 니 다. 당신 은 여전히 원 하 는 결 과 를 얻 지 못 할 것 입 니 다. 그러나 적어도 당신 은 경 고 를 받 을 것 입 니 다.
var counter = {
count: 0, // Strict-mode method
inc: function () { 'use strict'; this.count++; }
}
callIt(counter.inc); // TypeError: Cannot read property 'count' of undefined
console.log(counter.count);
예상 한 결 과 를 얻 으 려 면 bind () 를 사용 하 십시오.
var counter = {
count: 0,
inc: function () {
this.count++;
}
}
callIt(counter.inc.bind(counter));
// It worked! console.log(counter.count); // 1
bind () 는 항상 this 값 을 counter 로 설정 할 수 있 는 값 을 만 들 었 습 니 다. 의 함수.
4.3 this 를 숨 깁 니 다. 방법 에서 함 수 를 사용 할 때 함수 가 자신의 this 라 는 것 을 무시 합 니 다. 라 고 적 었 다.이것 또 방법 과 다 르 기 때문에 너 는 이 두 개의 this 를 섞어서 사용 하 다.구체 적 인 것 은 아래 코드 를 보십시오.
var obj = {
name: '
Jane'
,
friends: [ 'Tarzan', 'Cheeta' ],
loop: function () {
'
use strict';
this.friends.forEach(
function (friend) {
console.log(this.name+'
knows '
+friend);
} );
}
};
obj.loop(); // TypeError: Cannot read property 'name' of undefined
위의 예 에서 함수 중의 this. name 함수 의 this 때문에 사용 할 수 없습니다. 이것 과 방법 loop () 의 this 다르다다음은 이 문 제 를 해결 하기 위해 세 가지 방향 을 제공 했다.
loop: function () {
'
use strict'
var that = this;
this.friends.forEach(function (friend) {
console.log(that.name+' knows '+friend);
});
}
loop: function () {
'
use strict'
this.friends.forEach(function (friend) {
console.log(this.name+' knows '+friend);
}.bind(this));
}
loop: function () {
'
use strict';
this.friends.forEach(
function (friend) {
console.log(this.name+' knows '+friend);
},
this);
}
loop: function () {
'
use strict'; // The parameter of forEach() is an arrow function
this.friends.forEach(friend => { // `this` is loop’s `this`
console.log(this.name+' knows '+friend);
});
}
나 는 어떤 API 들 이 이것 을 실제 함수 의 추가 매개 변수 로 사용 하기:
beforeEach(function () {
this.addMatchers({
toBeInRange: function (start, end) {
...
}
});
});
내 현적 인 파 라 메 터 를 외 현적 인 모양 으로 써 서 입력 하면 코드 가 더욱 잘 이해 되 고 화살표 함수 의 요구 도 일치 합 니 다.
beforeEach(api => { api.addMatchers({ toBeInRange(start, end) { ... } }); });
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
「은행의 자산 운용 상품 관리 웹 시스템」의 소개시스템 개요 이 시스템은 중국의 각 은행 홈페이지에 게재 된 자산 운용 상품의 발행시기, 발행 지점 · 금리 등의 정보를 하나의 웹 사이트에 통합 사용자가 의견과 판매 정보를 쿼리 할 수 있습니다. 시스템을 도입하는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.