이에 대한 자세한 설명은 JavaScript로

黄舟
풀어 주다: 2017-03-03 15:34:51
원래의
938명이 탐색했습니다.

이것은 JavaScript에서 비교적 유연하며, 환경에 따라 또는 동일한 함수가 다른 방식으로 호출되는 경우에 달라질 수 있습니다. 하지만 라는 일반적인 원칙이 있습니다. 즉, 함수를 호출하는 객체를 가리킨다는 것입니다.

시리즈 목차

  • JavaScript의 클로저(Closure)에 대한 심층 소개

  • -JavaScript의 심층 소개

  • JavaScript의 프로토타입 체인 및 상속에 대한 심층 소개

다음은 제가 공부한 노트입니다. 8가지 상황으로 나열되어 있습니다.

전역 this(브라우저)

전역 범위에서 이는 일반적으로 브라우저의 창인 전역 객체를 가리킵니다. , 이 개체는 전역 개체입니다.

console.log(this.document === document); // true (document === window.document)
console.log(this === window); // true 
this.a = 37;  //相当于创建了一个全局变量a
console.log(window.a); // 37
로그인 후 복사

일반 함수의 이(브라우저)

일반 함수 선언 또는 함수 표현식입니다. 함수가 직접 호출되는 경우에도 브라우저에서는 이 객체가 전역 객체를 가리킵니다. 창. 노드에서 이 개체는 전역 개체입니다.

function f1(){  
  return this;  
} 
f1() === window; // true, global object
로그인 후 복사

또 다른 예를 들어보면 읽어보면 매우 명확해질 것입니다.

function test(){
 this.x = 1;
  alert(this.x);
}
test(); // 1
로그인 후 복사

이것이 전역 개체임을 증명하려면 코드를 일부 변경하세요.

var x = 1;
function test(){
 alert(this.x);
}
test(); // 1
로그인 후 복사

실행 결과는 여전히 1입니다. 다시 변경하세요:

var x = 1;
function test(){
 this.x = 0;
}
test();
alert(x); //0
로그인 후 복사

그러나 엄격 모드에서 일반 함수가 호출되면 이는 정의되지 않음을 가리키며, 이것이 노드가 엄격 모드를 사용하는 이유 중 하나입니다.

function f2(){  
  "use strict"; // see strict mode  
  return this; 
} 
f2() === undefined; // true
로그인 후 복사

객체 메소드의 함수로

객체 메소드로 사용하는 것이 일반적입니다.

다음 예에서는 객체 리터럴 o를 만듭니다. o에 속성 f가 있습니다. 그 값은 함수 객체입니다. 객체의 메소드로 호출되면 o

var o = {  
   prop: 37,  
   f: function() {    
     return this.prop;    
  } 
};  

console.log(o.f()); // logs 37
로그인 후 복사

객체를 가리킨다. 함수 리터럴처럼 반드시 객체를 정의할 필요는 없다. independent() 함수가 직접 호출되면 이는 창을 가리킬 것이지만 할당을 통해 일시적으로 속성 f를 만들고 함수 개체를 가리킬 때 여전히 37을 얻습니다.

var o = {prop: 37}; 

function independent() {  
   return this.prop; 
} 

o.f = independent;  
console.log(o.f()); // logs 37
로그인 후 복사

그래서 함수가 어떻게 만들어지든 상관은 없지만 함수가 객체의 메서드로 호출되는 한 이것은 객체를 가리킬 것입니다.

객체 프로토타입 체인의 this

다음 예에서는 먼저 속성 f와 함수가 있는 객체 o를 만듭니다. 객체 속성의 값으로 Object.create(o)를 통해 객체 p를 생성합니다. p는 빈 객체이고 해당 프로토타입은 o를 가리킨 다음 p.a = 1을 사용하여 속성을 생성합니다. 프로토타입에서 메소드 this.a, this.b를 호출하면 여전히 객체 p에서 a와 b를 얻을 수 있습니다. 여기서 주목해야 할 점은 p의 프로토타입이 o라는 것입니다. p.f()를 호출하면 프로토타입 체인에서 f 속성을 호출하여 현재 객체 p를 얻을 수 있습니다.

var o = {f:function(){ return this.a + this.b; }};
var p = Object.create(o); 
p.a = 1; 
p.b = 4; 
console.log(p.f()); // 5
로그인 후 복사

get/set 메소드와 get/set 메소드의 this

는 일반적으로 생성자의 get/set 메소드

function modulus(){   
   return Math.sqrt(this.re * this.re + this.im * this.im); 
} 
var o = { 
  re: 1, 
  im: -1, 
  get phase(){      
     return Math.atan2(this.im, this.re);    
  } 
}; 
Object.defineProperty(o, 'modulus', {       //临时动态给o对象创建modules属性
  get: modulus, enumerable:true, configurable:true}); 

console.log(o.phase, o.modulus); // logs -0.78 1.4142
로그인 후 복사

에 있는 객체를 가리킵니다. this

new를 사용하여 MyClass를 생성자로 호출하면 this는 빈 개체를 가리키고 이 개체의 프로토타입은 MyClass.prototype을 가리킵니다(프로토타입 체인 요약은 이 문서 참조). , 그러나 호출 당시 this.a = 37 의 할당이 이루어졌으므로 결국 this 를 반환 값으로 사용하게 됩니다(return 문을 작성하지 않거나 return이 기본형인 경우 this 두 번째 예에서는 return 문이 객체를 반환하고 a = 38이 반환 값으로 사용됩니다

function MyClass(){    
   this.a = 37; 
} 
var o = new MyClass();  
console.log(o.a); // 37 

function C2(){    
   this.a = 37;   
   return {a : 38};  
} 

o = new C2();  
console.log(o.a); // 38
로그인 후 복사

call/apply 메소드와 this

다양한 호출 방법 외에도 함수 개체의 일부 메서드는 호출/적용과 같은 함수 실행을 수정할 수 있습니다.

call이 매개변수를 플랫 방식으로 전달하는 반면 Apply는 배열을 전달한다는 점을 제외하면 호출과 적용 사이에는 기본적으로 차이가 없습니다. 아래 예시

언제 전화상담 및 신청을 해야 하나요? 예를 들어 Object.prototype.toString을 호출하고 싶지만 특정 this를 지정하려는 경우 Object.prototype.toString.call(this)을 사용하여 직접 호출할 수 없는 메서드를 호출할 수 있습니다. 다음 예를 들어보세요.

function add(c, d){  
   return this.a + this.b + c + d;  
} 
var o = {a:1, b:3}; 
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16     //第一个参数接收的是你想作为this的对象
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 

function bar() {  
   console.log(Object.prototype.toString.call(this)); 
} 
bar.call(7); // "[object Number]"
로그인 후 복사

bind 메소드와

bind 메소드는 es5부터 제공되므로 ie9+는

function f(){  
   return this.a;  
} 

var g = f.bind({a : "test"});   //想把某个对象作为this的时候,就把它传进去,得到一个新对象g
console.log(g()); // test       //重复调用的时候,this已经指向bind参数。这对于我们绑定一次需要重复调用依然实现绑定的话,会比apply和call更加高效(看下面这个例子)

var o = {a : 37, f : f, g : g};  
console.log(o.f(), o.g()); // 37, test  
 //o.f()通过对象的属性调用,this指向对象o;比较特殊的是即使我们把新绑定的方法作为对象的属性调用,o.g()依然会按之前的绑定去走,所以答案是test不是g
로그인 후 복사

Summary

만 지원합니다. 프로젝트 그제서야 이러한 기본 개념이 얼마나 중요한지 깨달았습니다. 하나씩 구현하지 않으면 정말 우연히 함정에 빠질 것입니다. 앞으로는 프로토타입 체인, 범위, 상속, 체인 호출, 규칙성 및 기타 지식도 요약할 것입니다. 팔로우를 환영합니다

위 내용은 JavaScript로 자세히 설명되어 있습니다. PHP 중국어 넷(www.php.cn)에 주목하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿