이 기사에서는 js에서 this의 사용법을 분석하기 위해 예제를 사용할 것입니다. 다음 예제에서 볼 수 있듯이 obj.foo()의 경우 foo는 obj 환경에서 실행됩니다. 따라서 이는 foo()의 경우 obj를 가리키고 foo는 전역 환경에서 실행되므로 전역 환경을 가리킵니다. 따라서 두 회사의 운영 결과는 다릅니다. 이것이 결정적인 역할을 한다고 볼 수 있습니다. 이 기사가 모든 사람에게 참고 가치를 제공할 수 있기를 바랍니다.
자바스크립트 언어를 배운다는 것은 다음 두 가지 작성 방법을 이해하는 것인데, 이에 따라 결과가 달라질 수 있습니다.
var obj = { foo: function () {} }; var foo = obj.foo; // 写法一 obj.foo() // 写法二 foo()
위 코드에서 obj.foo
와 foo
는 동일한 함수를 가리키더라도 실행 결과가 다를 수 있습니다. 아래 예를 참조하세요. obj.foo
和foo
指向同一个函数,但是执行结果可能不一样。请看下面的例子。
var obj = { foo: function () { console.log(this.bar) }, bar: 1 }; var foo = obj.foo; var bar = 2; obj.foo() // 1 foo() // 2
这种差异的原因,就在于函数体内部使用了this
关键字。很多教科书会告诉你,this
指的是函数运行时所在的环境。对于obj.foo()
来说,foo
运行在obj
环境,所以this
指向obj
;对于foo()
来说,foo
运行在全局环境,所以this
指向全局环境。所以,两者的运行结果不一样。
这种解释没错,但是教科书往往不告诉你,为什么会这样?也就是说,函数的运行环境到底是怎么决定的?举例来说,为什么obj.foo()
就是在obj
环境执行,而一旦var foo = obj.foo
,foo()
就变成在全局环境执行?
本文就来解释 JavaScript 这样处理的原理。理解了这一点,你就会彻底理解this
的作用。
JavaScript 语言之所以有this
的设计,跟内存里面的数据结构有关系。
var obj = { foo: 5 };
上面的代码将一个对象赋值给变量obj
。JavaScript 引擎会先在内存里面,生成一个对象{ foo: 5 }
,然后把这个对象的内存地址赋值给变量obj
。
也就是说,变量obj
是一个地址(reference)。后面如果要读取obj.foo
,引擎先从obj
拿到内存地址,然后再从该地址读出原始的对象,返回它的foo
属性。
原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象。举例来说,上面例子的foo
属性,实际上是以下面的形式保存的。
{ foo: { [[value]]: 5 [[writable]]: true [[enumerable]]: true [[configurable]]: true } }
注意,foo
属性的值保存在属性描述对象的value
属性里面。
这样的结构是很清晰的,问题在于属性的值可能是一个函数。
var obj = { foo: function () {} };
这时,引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo
属性的value
属性。
{ foo: { [[value]]: 函数的地址 ... } }
由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。
var f = function () {}; var obj = { f: f }; // 单独执行 f() // obj 环境执行 obj.f()
JavaScript 允许在函数体内部,引用当前环境的其他变量。
var f = function () { console.log(x); };
上面代码中,函数体里面使用了变量x
。该变量由运行环境提供。
现在问题就来了,由于函数可以在不同的运行环境执行,所以需要有一种机制,能够在函数体内部获得当前的运行环境(context)。所以,this
就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。
var f = function () { console.log(this.x); }
上面代码中,函数体里面的this.x
就是指当前运行环境的x
。
var f = function () { console.log(this.x); } var x = 1; var obj = { f: f, x: 2, }; // 单独执行 f() // 1 // obj 环境执行 obj.f() // 2
上面代码中,函数f
在全局环境执行,this.x
指向全局环境的x
。
在obj
环境执行,this.x
指向obj.x
이 차이가 나는 이유는 this
키워드가 함수 본문 내부에서 사용되기 때문입니다. 많은 교과서에서는 this
가 함수가 실행되는 환경을 참조한다고 알려줍니다. obj.foo()
의 경우 foo
는 obj
환경에서 실행되므로 this
는 obj를 가리킵니다.
; foo()
의 경우 foo
는 전역 환경에서 실행되므로 this
는 전역 환경을 가리킵니다. 따라서 두 회사의 운영 결과는 서로 다릅니다.
obj.foo()
가 obj
환경에서 실행되는 이유와 일단 var foo = obj.foo
, foo ()
가 글로벌 환경에서 실행되나요? 🎜🎜이 글에서는 이런 방식으로 자바스크립트 처리의 원리를 설명하겠습니다. 이것을 이해하면 이것
의 역할을 완전히 이해하게 될 것입니다. 🎜🎜2. 메모리의 데이터 구조 🎜🎜자바스크립트 언어가 이
를 디자인한 이유는 메모리의 데이터 구조와 관련이 있습니다. 🎜🎜rrreee🎜🎜위 코드는 obj
변수에 개체를 할당합니다. JavaScript 엔진은 먼저 메모리에 { foo: 5 }
객체를 생성한 다음 이 객체의 메모리 주소를 obj
변수에 할당합니다. 🎜🎜🎜🎜 즉, 변수 obj
는 주소(참조)입니다. 나중에 obj.foo
를 읽으려면 엔진이 먼저 obj
에서 메모리 주소를 가져온 다음 주소에서 원래 객체를 읽고 foo 속성입니다. 🎜🎜원본 개체는 사전 구조로 저장되며 각 속성 이름은 속성 설명 개체에 해당합니다. 예를 들어 위 예시의 <code>foo
속성은 실제로는 다음과 같은 형태로 저장됩니다. 🎜🎜🎜🎜rrreee🎜🎜주의 , foo
속성의 값은 속성 설명 객체의 value
속성에 저장됩니다. 🎜🎜3. 함수 🎜🎜이 구조는 매우 명확합니다. 문제는 속성의 값이 함수일 수 있다는 것입니다. 🎜🎜rrreee🎜🎜이때 엔진은 함수를 메모리에 따로 저장한 후 foo
속성의 value
속성에 함수의 주소를 할당합니다. . 🎜🎜🎜🎜rrreee🎜🎜마감 함수는 단일 값이므로 다양한 환경(컨텍스트)에서 실행될 수 있습니다. 🎜🎜rrreee🎜🎜4. 환경 변수🎜🎜JavaScript를 사용하면 함수 본문 내에서 현재 환경의 다른 변수를 참조할 수 있습니다. 🎜🎜rrreee🎜🎜위 코드에서는 x
변수가 함수 본문에 사용되었습니다. 이 변수는 런타임 환경에서 제공됩니다. 🎜🎜이제 문제가 발생합니다. 함수는 다양한 실행 환경에서 실행될 수 있으므로 함수 본문 내부에 현재 실행 환경(컨텍스트)을 가져오는 메커니즘이 필요합니다. 따라서 this
는 함수 본문 내부에서 함수의 현재 실행 환경을 참조하도록 디자인된 것입니다. 🎜🎜rrreee🎜🎜위 코드에서 함수 본문의 this.x
는 현재 실행 중인 환경의 x
를 나타냅니다. 🎜🎜rrreee🎜🎜위 코드에서 함수 f
는 전역 환경에서 실행되고, this.x
는 전역 환경의 x
를 가리킵니다. 환경. 🎜🎜🎜🎜in obj
환경 실행, this.x
는 obj.x
를 가리킵니다. 🎜🎜🎜🎜이 기사의 시작 부분에서 제기된 질문으로 돌아가서 obj.foo()
是通过obj
找到foo
,所以就是在obj
环境执行。一旦var foo = obj.foo
,变量foo
就直接指向函数本身,所以foo()
는 글로벌 환경에서 실행됩니다.
관련 추천:
위 내용은 js 이벤트에서 이것이 무엇을 의미합니까? js에서 this의 사용법에 대한 자세한 설명(사용 예 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!