>웹 프론트엔드 >JS 튜토리얼 >JavaScript로 이에 대한 자세한 답변(그래픽 튜토리얼)

JavaScript로 이에 대한 자세한 답변(그래픽 튜토리얼)

亚连
亚连원래의
2018-05-19 10:45:361245검색

JavaScript에서 함수의 this 개체는 함수가 실행되는 범위입니다(예: 웹 페이지의 전역 범위에서 함수가 호출될 때 this 개체는 창을 나타냅니다).

JavaScript의 이는 Java와 같은 객체 지향 언어의 이와 매우 다릅니다. 바인딩(), call() 및 Apply() 함수는 이것의 유연성을 더욱 확장합니다.

이 기사는 가독성을 보장하기 위해 직역이 아닌 무료 번역을 사용합니다. 또한, 이 글의 저작권은 원저자에게 있으며, 번역은 학습용으로만 사용됩니다.

자바스크립트 키워드를 이렇게 깊이 이해하지 못하면 때로는 예상치 못한 함정에 빠질 수도 있습니다. 여기서는 이것이 실제로 무엇을 가리키는지 판단하는 데 도움이 되는 5가지 일반 규칙을 요약했습니다. 모든 상황이 다루어지는 것은 아니지만 대부분의 일상적인 상황은 이러한 규칙을 사용하여 정확하게 추론할 수 있습니다.

이 값은 일반적으로 함수의 실행 환경에 따라 결정됩니다. 즉, 함수가 호출되는 방식에 따라 달라집니다.
동일한 함수가 호출될 때마다 this는 다른 개체를 가리킬 수 있습니다. (전역 개체)

Chrome 브라우저 개발자 패널을 열고(Windows: Ctrl + Shift + J) (Mac: Cmd + Option + J) 다음을 입력하세요.

console.log(this);

출력이 무엇인지 확인하세요.

// Window {}
console.log(this);

看看输出了什么?

myName
// 输出 'Brandon'

window对象! 因为在全局作用域下,this指向全局对象。在浏览器中全局对象就是window对象。
为了让你更加清楚理解为什么this会指向window对象,我们来看另外一个例子:

var myName = 'Brandon';
我们可以通过在控制台输入myName来访问其值:

window.myName
// 输出 'Brandon'
window.myName === myName
// 输出 true

其实,所有在全局定义的变量都绑定到window对象。我们来做如下测试:

function test(){
 return this;
}
test();

现在我们将this放到函数内部,看看有何效果。

var person = {
 first: 'John',
 last: 'Smith', 
 full: function() {
  console.log(this.first + ' ' + this.last);
 }
};
person.full();
// 输出 'John Smith'

你会发现this依然指向全局的window对象。因为this关键字没有处于一个声明的对象内部,默认指向全局window对象。这一点可能对于大部分初学者来说有点难以理解。当读完这篇文章,你就会豁然开朗。
注意:如果在strcit模式下,上面的例子中this为undefined。

声明的对象 (Declared Object)

当this关键字在一个声明对象内部使用,其值会被绑定到调用该this的函数的最近的父对象。我们用例子来说明这个问题:

var person = {
 first: 'John',
 last: 'Smith', 
 full: function() {
  console.log(this);
 }
};
person.full();
// 输出 Object {first: "John", last: "Smith", full: function}

在被声明的对象person中的full函数里面使用了this, 那么调用this的full函数的最近的父对象就是person, 因此,this指向person。

为了更好的描述this实际上是指向person对象的,你可以拷贝如下代码到浏览器控制台,将this打印出来。

var person = {
 first: 'John',
 last: 'Smith',
 full: function() {
  console.log(this.first + ' ' + this.last);
 },
 personTwo: {
  first: 'Allison',
  last: 'Jones',
  full: function() {
   console.log(this.first + ' ' + this.last);
  }
 }
};

我们接下来看一个更复杂的例子:

person.full();
// 输出 'John Smith'
person.personTwo.full();
// 输出 'Allison Jones'

在这里我们有嵌套的对象,在这个时候,this分别指向谁呢? 我们将其打印出来看一看:

function Car(make, model) {
 this.make = make;
 this.model = model;
};

你会发现满足我们前面所描述的规则:其值会被绑定到调用this的函数的最近的父对象。

new关键字

当使用new关键字构建一个新的对象,this会绑定到这个新对象。我们来看一个例子:

var myCar = new Car('Ford', 'Escape');
console.log(myCar);
// 输出 Car {make: "Ford", model: "Escape"}

根据第一条规则,你可能会推断this指向全局对象。但是如果我们使用new关键字来声明一个新的变量,Car函数中的this将会绑定一个新的空对象,然后初始化this.make和this.model的值。

function add(c, d) {
 console.log(this.a + this.b + c + d);
}
add(3,4);
// 输出 NaN

call, bind, 和apply

我们可以显示的在call(),bind(),apply()中设置this的绑定对象。这三个函数很类似,但是我们需要注意它们微小的区别。

d7ee23e7ba694ae212761bca76923316

我们来看一个例子:

function add(c, d) {
 console.log(this.a + this.b + c + d);
}
var ten = {a: 1, b: 2};
add.call(ten, 3, 4);
// 输出 10
add.apply(ten, [3,4]);
// 输出 10

add函数输出NaN, 因为this.a和this.b未定义。

现在我们引入对象,并且使用call()和apply()来调用:

var small = {
 a: 1,
 go: function(b,c,d){
  console.log(this.a+b+c+d);
 }
}
var large = {
 a: 100
}

当我们使用add.call(),第一个参数是this需要绑定的对象,剩下的是add函数本来的参数。
因此,this.a指向ten.a,this.b指向ten.b。add.apply()也类似,除了第二个参数是一个数组,用于存储add函数的参数。

bind()函数和call()类似,但是bind()函数不会立即被调用。bind()函数会返回一个函数,并且将this绑定好。接下来我们来用例子来帮助理解bind()函数的应用场景:

small.go(2, 3, 4);
// 输出 10

执行:

small.go.call(large, 2, 3, 4);
// 输出 109

如果我们想使用large.a的值,而不是small.a呢? 我们可以使用call/apply:

console.log(bindTest);
// 输出 function (b,c,d){console.log(this.a+b+c+d);}

但是,如果我们现在还不知道这三个参数应该传入什么值,应该怎么办呢? 我们可以使用bind:

var bindTest = small.go.bind(large, 2);창 개체! 전역 범위에서 이는 전역 개체를 가리키기 때문입니다. 브라우저의 전역 개체는 창 개체입니다.

이것이 window 개체를 가리키는 이유를 더 명확하게 이해하기 위해 다른 예를 살펴보겠습니다.

var myName = 'Brandon';

콘솔에 myName을 입력하여 해당 값에 액세스할 수 있습니다. :

bindTest(3, 4);
// 输出 109

사실 전역적으로 정의된 모든 변수는 window 객체에 바인딩됩니다. 다음 테스트를 해보자:

rrreee

이제 이것을 함수 안에 넣어서 어떤 효과가 있는지 살펴보자.

rrreee🎜이것은 여전히 ​​전역 창 개체를 가리킨다는 것을 알 수 있습니다. this 키워드는 선언된 객체 내에 있지 않기 때문에 기본값은 전역 창 객체입니다. 대부분의 초보자가 이해하기에는 다소 어려울 수 있습니다. 이 글을 읽고 나면 문득 이해가 되실 겁니다. 🎜참고: strcit 모드인 경우 위 예에서는 정의되지 않습니다. 🎜🎜🎜Declared Object🎜🎜🎜this 키워드가 선언된 객체 내에서 사용되면 해당 값은 이를 호출하는 함수의 가장 가까운 상위 객체에 바인딩됩니다. 이 문제를 설명하기 위해 예를 사용하겠습니다. 🎜rrreee🎜이것이 선언된 객체 person의 전체 함수에서 사용되면 이를 호출하는 전체 함수의 가장 가까운 상위 객체는 person이므로 이는 person을 가리킵니다. 🎜🎜이것이 실제로 사람 객체를 가리킨다는 것을 더 잘 설명하기 위해 다음 코드를 브라우저 콘솔에 복사하고 인쇄할 수 있습니다. 🎜rrreee🎜다음에는 좀 더 복잡한 예를 살펴보겠습니다. 🎜rrreee🎜여기에 중첩된 개체가 있습니다. 이 시점은 누구를 가리키는 것일까요? 인쇄하여 살펴보겠습니다. 🎜rrreee🎜 앞서 설명한 규칙이 충족되는 것을 확인할 수 있습니다. 해당 값은 이것을 호출한 함수의 가장 가까운 상위 개체에 바인딩됩니다. 🎜🎜🎜new 키워드🎜🎜🎜new 키워드를 사용하여 새 개체를 생성하면 새 개체에 바인딩됩니다. 예를 살펴보겠습니다. 🎜rrreee🎜첫 번째 규칙에 따르면 이것이 전역 객체를 가리킨다고 추론할 수 있습니다. 하지만 new 키워드를 사용하여 새 변수를 선언하면 Car 함수의 this가 새로운 빈 개체에 바인딩되고 this.make 및 this.model의 값이 초기화됩니다. 🎜rrreee🎜🎜call, 바인딩 및 적용🎜🎜🎜call(), 바인딩() 및 Apply()에서 이것의 바인딩 개체를 명시적으로 설정할 수 있습니다. 이 세 가지 기능은 매우 유사하지만 미묘한 차이점에 주의할 필요가 있습니다. 🎜🎜aaf871443a1ce03c109bb25b8cc637c0🎜🎜예를 살펴보겠습니다. 🎜rrreee🎜add 함수는 NaN을 출력합니다. 왜냐하면 this.a와 this.b가 정의되지 않았기 때문입니다. 🎜🎜이제 개체를 소개하고 call() 및 apply()를 사용하여 다음을 호출합니다. 🎜rrreee🎜 add.call()을 사용할 때 첫 번째 매개변수는 바인딩해야 하는 개체이고 나머지는 함수 자체 매개변수를 추가합니다. 🎜따라서 this.a는 ten.a를 가리키고, this.b는 ten.b를 가리킵니다. add.apply()는 두 번째 매개변수가 add 함수의 매개변수를 저장하는 배열이라는 점을 제외하면 유사합니다. 🎜🎜bind() 함수는 call()과 유사하지만, 바인딩() 함수는 즉시 호출되지 않습니다. 바인딩() 함수는 함수를 반환하고 이를 바인딩합니다. 다음으로, 바인딩() 함수의 적용 시나리오를 이해하는 데 도움이 되는 예를 사용하겠습니다. 🎜rrreee🎜실행: 🎜rrreee🎜small.a 대신 Large.a의 값을 사용하려면 어떻게 해야 할까요? call/apply를 사용할 수 있습니다:🎜rrreee🎜하지만 이 세 가지 매개변수에 대해 어떤 값을 전달해야 하는지 아직 모른다면 어떻게 해야 할까요? 다음과 같이 바인드를 사용할 수 있습니다:🎜🎜var binTest = small.go.bind(large, 2);🎜🎜콘솔 아래에 바인딩 테스트를 인쇄하면 다음이 표시됩니다. 🎜rrreee🎜참고: 이 함수는 이것을 대형 객체에 바인딩하고 첫 번째 매개변수에 전달했습니다. b. 따라서 다음으로 나머지 매개변수를 전달해야 합니다. 🎜rrreee🎜위 내용은 제가 모든 사람을 위해 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다. 🎜🎜관련 기사: 🎜

JS에서 this 포인팅과 호출 및 적용 기능(그림 및 텍스트 튜토리얼)

JS에서 this 포인팅과 호출 및 적용 기능_기본 지식

self , in PHP static과 $this의 차이점과 후기 정적 바인딩

에 대한 자세한 설명

위 내용은 JavaScript로 이에 대한 자세한 답변(그래픽 튜토리얼)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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