JavaScript에서 이는 항상 혼란스럽고 js의 잘 알려진 함정 중 하나입니다. 개인적으로 저는 js에서의 이것이 좋은 디자인이 아니라고 생각합니다. 이것의 늦은 바인딩 특성으로 인해 전역 객체가 될 수도 있고, 현재 객체가 될 수도 있고, 심지어 어떤 사람들은 크기 때문에 이것을 사용하지도 않습니다. 함정.
사실 이것의 작동 원리를 완전히 이해한다면 당연히 이런 구덩이에 빠지지 않을 것입니다. 다음 상황에서 이것이 무엇을 가리키는지 살펴보겠습니다.
1. 전역 코드의 this
1 Alert(x);
// 전역 변수 x의 값은 2입니다. 🎜>
전역 범위에서 이는 브라우저의 창인 전역 개체를 가리킵니다.
function fooCoder(x) {
this.x = x;
}
fooCoder(2);
alert(x) ;
//전역변수 x의 값은 2
여기서는 전역 객체, 즉 윈도우를 가리킨다. 엄격 모드에서는 정의되지 않습니다.
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth) {
console.log(this.name + " say " + sth);
}
}
person.hello("hello world");
5. 내부 함수
var name = "clever coder";
name : "foocoder",
hello : function( sth){
var sayhello = function(sth) {
console.log(this.name + " say " + sth);
};
sayhello(
}
//clever coder presents hello world
내부 함수에서는 예상대로 바인딩되지 않습니다. 대신 , 이는 전역 객체에 바인딩됩니다. 이는 일반적으로 JavaScript 언어에서 설계 오류로 간주됩니다. 왜냐하면 아무도 내부 함수에서 이것을 전역 객체로 지정하는 것을 원하지 않기 때문입니다. 그 사람 또는 자기 자신이 되기로 동의함:
var name = "clever coder";
var person = {
name : "foocoder",
hello : function(sth){
var that = this;
var sayhello = function(sth) {
console.log(that.name + " say " + sth);
};
sayhello(sth);
}
}
person.hello("hello world");
//foocoder presents hello world
call을 사용하여 적용하고 설정
call( thisArg [, arg1, arg2, ... ] );
// 매개변수 목록, arg1, arg2, ...
apply(thisArg [, argArray] ) ;
// 매개변수 배열, argArray
둘 다 함수를 특정 객체에 바인딩하는 데 사용됩니다. 당연히 이때는 명시적으로 로 설정됩니다. 첫 번째 매개변수.
페이드 아웃 함수로 함수가 호출되면 this는 전역 개체를 가리킵니다(엄격 모드에서는 정의되지 않음).
생성자의 This는 새로 생성된 개체를 가리킵니다
중첩된 개체의 This 함수는 상위 수준 함수를 상속하지 않습니다. 필요한 경우 변수를 사용하여 상위 계층 함수의 this를 저장할 수 있습니다.
간단히 정리하면 함수에 사용하면 객체가 함수를 직접 호출할 때만 객체를 가리킵니다.
obj.foocoder();
foocoder.call(obj, ...);
foocoder.apply(obj, ...);
그렇다면 콜백 함수 바인딩 문제를 어떻게 해결할 수 있을까요? ES5에는 새로운 메소드인 바인딩():
fun.bind(thisArg[, arg1[, arg2[, ...]]])
바운드 함수가 호출되면 이 매개변수는 실행 시 원래 함수의 this 지점으로 사용됩니다. new 연산자를 사용하여 바인딩된 함수를 호출하는 경우 이 매개변수는 유효하지 않습니다.
1 arg1, arg2 , ...
바운드 함수가 호출되면 이러한 매개변수와 바인딩된 함수 자체의 매개변수가 순서대로 실행될 때 원래 함수의 매개변수로 사용됩니다.
이 메소드는 바인딩 함수라는 새로운 함수를 생성합니다. 바인딩 함수는 이를 생성할 때 바인딩 메소드에 전달된 첫 번째 매개변수를 사용하고, 바인드 메소드에 전달된 두 번째 및 후속 매개변수를 사용합니다. 매개변수와 실행 시 바인딩된 함수 자체의 매개변수를 원래 함수의 매개변수로 순서대로 사용하여 원래 함수를 호출합니다.
분명히 바인딩 메서드는 위의 문제를 잘 해결할 수 있습니다.
1
2 $("#some-ele").click(person.hello.bind(person));
//해당 요소를 클릭하면 출력 foocoder에 hello world가 표시됩니다
사실 이 메서드도 시뮬레이션하기 쉽습니다. Prototype.js의 바인딩 메서드 소스 코드를 살펴보겠습니다.
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
return function(){
return fn.apply(object ,
args.concat(Array.prototype.slice.call(arguments)));
};
};