이전 글 "중추절 팁: CSS를 사용하여 지구와 달의 혁명을 구현하는 방법(컬렉션) "에서 CSS를 사용하여 지구와 달의 혁명을 구현하는 방법을 소개했습니다. 달. 다음 글은 js의 포인팅 문제를 이해하는 데 도움이 될 것입니다. 이는 특정 참조 가치가 있으므로 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
저를 믿으세요. 이 기사의 7단계를 기억하는 한 JS에서 포인팅하는 이
를 완전히 마스터할 수 있습니다. this
指向。
先念口诀:箭头函数、new、bind、apply 和 call、欧比届点(obj.)、直接调用、不在函数里。
按照口诀的顺序,只要满足前面某个场景,就可以确定this
指向了。
接下来按照口诀顺序对它们进行详解,文中示例代码都运行在Chrome
的Console
控制台中。
文末有精心准备的练习题,用于检验学习成果,别忘了试试~
箭头函数排在第一个是因为它的this
不会被改变,所以只要当前函数是箭头函数,那么就不用再看其他规则了。
箭头函数的this
是在创建它时外层this
的指向。这里的重点有两个:
1、创建箭头函数时,就已经确定了它的this
指向。
2、箭头函数内的this
指向外层的this
。
所以要知道箭头函数的this
就得先知道外层this
的指向,需要继续在外层应用七步口诀。
当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象。
读者可能会有疑问,“如果使用new
关键调用箭头函数,是不是箭头函数的this
就会被修改呢?”。
我们在控制台试一下。
func = () => {} new func() // throw error
从控制台中可以看出,箭头函数不能当做构造函数,所以不能与new
一起执行。
bind 是指 Function.prototype.bind() 详细地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
易错点
function func() { console.log(this) } func.bind(1).bind(2)() // 1
func = () => { // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」 console.log(this) } func.bind(1)() // Window,口诀 1 优先
易错点
function func() { console.log(this, this.__proto__ === func.prototype) } boundFunc = func.bind(1) new boundFunc() // Object true,口诀 2 优先
apply()
和 call()
的第一个参数都是this
,区别在于通过apply
调用时实参是放到数组中的,而通过call
调用时实参是逗号分隔的。
易错点
func = () => { // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」 console.log(this) } func.apply(1) // Window,口诀 1 优先
易错点
function func() { console.log(this) } boundFunc = func.bind(1) boundFunc.apply(2) // 1,口诀 3 优先
function func() { console.log(this.x) } obj = { x: 1 } obj.func = func obj.func() // 1
这里就不用代码例证箭头函数和 bind 函数的优先级更高了,有兴趣可自行尝试吧。
在函数不满足前面的场景,被直接调用时,this
将指向全局对象。在浏览器环境中全局对象是Window
,在Node.js
环境中是Global
。
先来个简单的例子。
function func() { console.log(this) } func() // Window
来一个复杂的例子,外层的outerFunc
就起个迷惑目的。
function outerFunc() { console.log(this) // { x: 1 } function func() { console.log(this) // Window } func() } outerFunc.bind({ x: 1 })()
不在函数中的场景,可分为浏览器的<script />
标签里,或Node.js
的模块文件里。
1、在<script />
标签里,this
指向Window
。
2、在Node.js
的模块文件里,this
指向Module
的默认导出对象,也就是module.exports
。
严格模式是在ES5
提出的。在ES5
规范之前,也就是非严格模式下,this
不能是undefined
或null
。所以**在非严格模式下,通过上面七步口诀,如果得出this
指向是undefined
或null
,那么this
会指向全局对象。**在浏览器环境中全局对象是Window
,在Node.js
环境中是Global
。
例如下面的代码,在非严格模式下,this
this
가 가리키는 위치를 결정할 수 있습니다. 다음으로, 본 글의 샘플 코드는 모두 Chrome
의 Console
콘솔에서 실행되는 순서대로 자세히 설명하겠습니다.
이
이기 때문입니다. 변경되지 않으므로 현재 함수가 화살표 함수인 한 다른 규칙을 볼 필요가 없습니다. 🎜🎜화살표 함수의 this
는 생성 당시 외부 this
의 지점입니다. 여기에는 두 가지 핵심 사항이 있습니다. 🎜🎜1. 화살표 함수를 만들 때 해당 this
포인터가 결정되었습니다. 🎜🎜2. 화살표 함수 내부의 this
는 외부 레이어의 this
를 가리킵니다. 🎜🎜그래서 화살표 함수의 이
를 알려면 먼저 바깥 레이어 이
의 방향을 알아야 하고, 계속해서 7단계 공식을 적용해야 합니다. 바깥층에. 🎜🎜2. new🎜🎜new 키워드를 사용하여 함수를 호출할 때 함수 내의 this는 JS에서 생성된 새 객체여야 합니다. 🎜🎜 독자들은 "새
키를 사용하여 화살표 함수를 호출하면 화살표 함수의 이
가 수정되나요?"라는 질문을 할 수 있습니다. 🎜🎜콘솔에서 해보자. 🎜function a() { console.log("function a:", this) ;(() => { console.log("arrow function: ", this) })() } a() a.bind(null)() a.bind(undefined)() a.bind().bind(2)() a.apply()
new
와 함께 실행할 수 없습니다. 🎜🎜3.bind🎜🎜🎜bind는 Function.prototype.bind()를 참조합니다. 상세 주소: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind🎜🎜 🎜여러 번 바인딩하면 첫 번째 바인드 값만 인식됩니다🎜🎜오류가 발생하기 쉬운 지점🎜"use strict" function a() { console.log("function a:", this) ;(() => { console.log("arrow function: ", this) })() } a() a.bind(null)() a.bind(undefined)() a.bind().bind(2)() a.apply()
function func(num) { this.count++ } func.count = 0 func(1)
obj = { func() { const arrowFunc = () => { console.log(this._name) } return arrowFunc }, _name: "obj", } obj.func()() func = obj.func func()() obj.func.bind({ _name: "newObj" })()() obj.func.bind()()() obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })()
apply()
와 call()
의 첫 번째 매개변수는 모두 이
입니다. 차이점은 apply
실제 매개변수는 배열에 배치되며, call
을 통해 호출되면 실제 매개변수는 쉼표로 구분됩니다. 🎜🎜화살표 함수의 이 부분은 수정되지 않습니다🎜🎜오류가 발생하기 쉬운🎜// obj // undefined // newObj // undefined // bindObj
this
는 전역 개체를 가리킵니다. 전역 개체는 브라우저 환경에서는 Window
이고 Node.js
환경에서는 Global
입니다. 🎜🎜먼저 간단한 예를 들어보겠습니다. 🎜rrreee🎜외부 outerFunc
는 혼란을 야기하는 복잡한 예를 들어보겠습니다. 🎜rrreee🎜7.함수에 없음<script />
태그 또는 로 나눌 수 있습니다. Node.js< /code> 모듈 파일. 🎜🎜1. <script />
태그에서 this
는 Window
를 가리킵니다. 🎜🎜2 Node.js
의 모듈 파일에서 this
는 Module
의 기본 내보내기 개체인 module을 가리킵니다. .내보내기
. 🎜🎜비엄격 모드🎜🎜엄격 모드는 ES5
에서 제안되었습니다. ES5
사양 이전, 즉 비엄격 모드에서는 this
가 정의되지 않음
또는 null
일 수 없었습니다. 따라서 ** 비엄격 모드에서 위의 7단계를 통해 this
가 undefine
또는 null
을 가리키는 것으로 결론이 나면 < code> this
는 전역 개체를 가리킵니다. **전역 개체는 브라우저 환경에서는 Window
이고 Node.js
환경에서는 Global
입니다. 🎜🎜예를 들어 다음 코드의 비엄격 모드에서 this
는 모두 전역 개체를 가리킵니다. 🎜rrreee🎜비엄격 모드의 실행 결과는 다음과 같습니다. 🎜🎜🎜🎜在严格模式下,执行同样的代码进行对比。记住要一次性将所有代码复制粘贴到控制台中,才能运行在严格模式下(因为第一行 "use strict
" 才会对后面的代码生效)。
"use strict" function a() { console.log("function a:", this) ;(() => { console.log("arrow function: ", this) })() } a() a.bind(null)() a.bind(undefined)() a.bind().bind(2)() a.apply()
严格模式下执行结果为:
七步口诀在严格模式下和非严格模式下都是完备的,只是在非严格模式下null
或undefined
会被转换为全局对象。所以我没有将这点列入口诀中。
先背诵口诀再做题,“箭头函数、new
、bind
、apply
和call
、欧比届点(obj.
)、直接调用、不在函数里”。
1. 下面代码执行后,func.count 值为多少?
function func(num) { this.count++ } func.count = 0 func(1)
答案
func.count
值为 0。
按照口诀,func()
调用时属于第 6 类「直接调用」。在非严格模式下,this
指向全局对象。this
跟func
一点关系都没有,所以 func.count
保持不变so easy
。
obj = { func() { const arrowFunc = () => { console.log(this._name) } return arrowFunc }, _name: "obj", } obj.func()() func = obj.func func()() obj.func.bind({ _name: "newObj" })()() obj.func.bind()()() obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })()
答案
// obj // undefined // newObj // undefined // bindObj
是不是很简单,你学废了吗?
推荐学习:JS视频教程
위 내용은 js의 포인팅 문제를 설명하는 기사(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!