>웹 프론트엔드 >JS 튜토리얼 >JavaScript 이 포인터 샘플 코드에 대한 자세한 설명

JavaScript 이 포인터 샘플 코드에 대한 자세한 설명

黄舟
黄舟원래의
2017-03-10 15:13:43958검색

JavaScript에서 이것의 의미는 매우 풍부합니다. 함수가 호출되는 방식에 따라 전역 객체, 현재 객체 또는 임의의 객체가 될 수 있습니다. 함수는 객체 메서드, 함수, 생성자, 적용 또는 호출과 같은 방법으로 호출할 수 있습니다.

객체 메소드 호출

객체 메소드로 호출되면 객체에 바인딩됩니다.

var point = { 
 x : 0, 
 y : 0, 
 moveTo : function(x, y) { 
     this.x = this.x + x; 
     this.y = this.y + y; 
     } 
 }; 

 point.moveTo(1, 1)//this 绑定到当前对象,即 point 对象

여기서 한 가지 강조하고 싶은 점은 함수가 정의될 ​​때가 아니라 함수가 실행될 때 해당 값을 얻는다는 것입니다. 객체 메서드 호출이라 하더라도 해당 메서드의 함수 속성이 함수 이름의 형태로 다른 범위에 전달되면 this의 포인터가 변경됩니다. 예를 들어보겠습니다.

var a = {
	aa : 0,
	bb : 0,
	fun : function(x,y){
		this.aa = this.aa + x;
		this.bb = this.bb + y;
	}
};
var aa = 1;
var b = {
	aa:0,
	bb:0,
	fun : function(){return this.aa;}
}	
a.fun(3,2);
document.write(a.aa);//3,this指向对象本身
document.write(b.fun());//0,this指向对象本身
(function(aa){//注意传入的是函数,而不是函数执行的结果
	var c = aa();
	document.write(c);//1 , 由于fun在该处执行,导致this不再指向对象本身,而是这里的window
})(b.fun);

그렇습니다. 이곳은 혼란스러운 곳이 될 수 있습니다.

함수 호출

함수는 직접 호출할 수도 있습니다. 이때 전역 개체에 바인딩됩니다.

 var x = 1;
  function test(){
    this.x = 0;
  }
  test();
  alert(x); //0

그러나 이는 몇 가지 문제를 일으킬 것입니다. 즉, 함수 내부에 정의된 함수의 경우 이것은 또한 우리가 원하는 것과 정반대인 전역 세계를 가리킬 것입니다. 코드는 다음과 같습니다.

var point = { 
 x : 0, 
 y : 0, 
 moveTo : function(x, y) { 
     // 内部函数
     var moveX = function(x) { 
     this.x = x;//this 绑定到了全局
    }; 
    // 内部函数
    var moveY = function(y) { 
    this.y = y;//this 绑定到了全局
    }; 

    moveX(x); 
    moveY(y); 
    } 
 }; 
 point.moveTo(1, 1); 
 point.x; //==>0 
 point.y; //==>0 
 x; //==>1 
 y; //==>1

원하는 이동 효과가 완료되지 않았을 뿐만 아니라 전역 변수가 두 개 더 있다는 것을 알 수 있습니다. 그렇다면 어떻게 해결해야 할까요? 함수 안에 함수를 입력할 때 이것을 변수에 저장한 후, 그 변수를 사용하면 됩니다. 코드는 다음과 같습니다.

var point = { 
 x : 0, 
 y : 0, 
 moveTo : function(x, y) { 
      var that = this; 
     // 内部函数
     var moveX = function(x) { 
     that.x = x; 
     }; 
     // 内部函数
     var moveY = function(y) { 
     that.y = y; 
     } 
     moveX(x); 
     moveY(y); 
     } 
 }; 
 point.moveTo(1, 1); 
 point.x; //==>1 
 point.y; //==>1

생성자 호출

JavaScript에서 생성자를 직접 생성할 때 이를 사용하여 새로 생성된 객체를 가리킬 수 있습니다. 이렇게 하면 함수의 this가 전역 세계를 가리키는 것을 방지할 수 있습니다.

 var x = 2;
  function test(){
    this.x = 1;
  }
  var o = new test();
  alert(x); //2

적용 또는 호출

이 두 가지 방법은 함수 실행의 컨텍스트를 전환할 수 있습니다. 즉, 여기에 바인딩된 개체를 변경할 수 있습니다. . 적용과 호출은 유사합니다. 차이점은 매개변수를 전달할 때 한 가지 요구사항은 배열이고 다른 요구사항은 별도로 전달된다는 것입니다. 그래서 Apply를 예로 들겠습니다:

<pre name="code" class="html">var name = "window";

var someone = {
    name: "Bob",
    showName: function(){
        alert(this.name);
    }
};

var other = {
    name: "Tom"
};   

someone.showName();		//Bob
someone.showName.apply();    //window
someone.showName.apply(other);    //Tom

객체의 메소드에 정상적으로 접근하면 this가 객체를 가리키는 것을 볼 수 있습니다. Apply를 사용한 후 Apply에 매개변수가 없으면 this의 현재 개체는 전역 개체입니다. Apply에 매개변수가 있으면 this의 현재 개체가 매개변수입니다.

화살표 함수 호출

여기에 한 가지 추가해야 할 점은 차세대 자바스크립트 표준 ES6에서는 화살표 함수는 함수가 정의될 ​​때 항상 this를 가리키고 실행될 때 를 가리킵니다. 예를 통해 이해해 봅시다.

var o = {
    x : 1,
    func : function() { console.log(this.x) },
    test : function() {
        setTimeout(function() {
            this.func();
        }, 100);
    }
};

o.test(); // TypeError : this.func is not a function

위 코드는 this의 포인터가 o에서 전역으로 바뀌기 때문에 오류가 발생합니다. 위 코드를 다음과 같이 수정해야 합니다.

var o = {
    x : 1,
    func : function() { console.log(this.x) },
    test : function() {
        var _this = this;
        setTimeout(function() {
            _this.func(); 
        }, 100);
    }
};

o.test();

미리 외부에 저장해둔 이것을 사용하면 됩니다. 여기서 화살표 함수를 사용할 수 있습니다. 화살표 함수의 this는 항상 this이 아닌 🎜>로 정의됩니다. 따라서 위의 코드를 다음과 같이 수정합니다.

var o = {
    x : 1,
    func : function() { console.log(this.x) },
    test : function() {
        setTimeout(() => { this.func() }, 100);
    }
};

o.test();

이번에는 o를 가리킬 것입니다. 또한 주의해야 할 점은 호출 및 적용이 가리키는 개체를 변경하지 않는다는 것입니다. 이것을 변경하십시오. 그러나 화살표 기능에서는 유효하지 않습니다.

var x = 1,
    o = {
        x : 10,
        test : () => this.x
    };

o.test(); // 1
o.test.call(o); // 依然是1

이렇게 하면 다양한 상황에서 이 바인딩 개체의 차이점을 이해할 수 있습니다.


위 내용은 JavaScript 이 포인터 샘플 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.