Maison >interface Web >js tutoriel >Un article expliquant le problème de ce pointage en js (avec code)
Dans l'article précédent "Conseils pour le festival de la mi-automne : Comment utiliser CSS pour réaliser la révolution de la terre et de la lune (Collection) ", je vous ai présenté comment utiliser CSS pour réaliser la révolution de la terre et de la lune. lune. L'article suivant vous aidera à comprendre ce problème de pointage dans js. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Croyez-moi, tant que vous vous souvenez des 7 étapes de cet article, vous pouvez complètement maîtriser le pointage this
en 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></script>
标签里,或Node.js
的模块文件里。
1、在<script></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
. Ensuite, nous les expliquerons en détail dans l'ordre des formules. Les exemples de codes de cet article sont tous exécutés dans la console Console
de Chrome
.
ce
. n'est pas modifié, donc tant que la fonction actuelle est une fonction fléchée, il n'est pas nécessaire de consulter d'autres règles. 🎜🎜Le this
de la fonction flèche est le point du this
externe lorsqu'il est créé. Il y a deux points clés ici : 🎜🎜1. Lors de la création d'une fonction flèche, son pointeur this
a été déterminé. 🎜🎜2. this
à l'intérieur de la fonction flèche pointe vers this
dans la couche externe. 🎜🎜Donc, pour connaître le this
de la fonction flèche, vous devez d'abord connaître la direction de la couche externe this
, et vous devez continuer à appliquer la formule en sept étapes dans la couche externe. 🎜🎜2. new🎜🎜Lors de l'utilisation du mot-clé new pour appeler une fonction, celui-ci dans la fonction doit être un nouvel objet créé par JS. 🎜🎜Les lecteurs peuvent avoir des questions : "Si vous utilisez la touche new
pour appeler une fonction fléchée, le this
de la fonction fléchée sera-t-il modifié ?". 🎜🎜Essayons-le sur la console. 🎜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()🎜🎜 🎜Comme vous pouvez le voir sur la console, les fonctions fléchées ne peuvent pas être utilisées comme constructeurs, elles ne peuvent donc pas être exécutées avec
new
. 🎜🎜3. bind🎜🎜🎜bind fait référence à Function.prototype.bind() Adresse détaillée : https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind🎜🎜 🎜Lors de la liaison plusieurs fois, seule la valeur de la première liaison est reconnue🎜🎜Point sujet aux erreurs🎜"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()🎜cela dans la fonction flèche ne sera pas modifié🎜
function func(num) { this.count++ } func.count = 0 func(1)🎜bind et new🎜🎜Point sujet aux erreurs🎜
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" })()🎜4. apply et call🎜🎜 Le premier paramètre de
apply()
et call()
est tous deux this
. La différence est que lors de l'appel via // obj // undefined // newObj // undefined // bindObj🎜Ceci dans la fonction de liaison ne sera pas modifié🎜🎜Sujet aux erreurs🎜rrreee🎜5 Obj (obj.)🎜rrreee🎜Pas nécessaire ici. La fonction de flèche de l'exemple de code et la fonction de liaison ont une priorité plus élevée. Si vous êtes intéressé, vous pouvez l'essayer vous-même. 🎜🎜6. Appel direct🎜🎜Lorsque la fonction ne répond pas au scénario précédent et est appelée directement,
this
pointera vers l'objet global. L'objet global est Window
dans l'environnement du navigateur et Global
dans l'environnement Node.js
. 🎜🎜Prenons d’abord un exemple simple. 🎜rrreee🎜Prenons un exemple compliqué. Le outerFunc
externe sert à créer de la confusion. 🎜rrreee🎜7. Pas dans une fonction<script></script>
du navigateur, ou . Fichier de module Node.js. 🎜🎜1. Dans la balise <script></script>
, this
pointe vers Fenêtre
. 🎜🎜2. Dans le fichier module de Node.js
, this
pointe vers l'objet d'exportation par défaut de Module
, qui est module. .exporte
. 🎜🎜Mode non strict🎜🎜Le mode strict a été proposé dans ES5
. Avant la spécification ES5
, c'est-à-dire en mode non strict, this
ne pouvait pas être indéfini
ou null
. Donc ** en mode non strict, via la formule en sept étapes ci-dessus, s'il est conclu que this
pointe vers undefined
ou null
, alors this
pointera vers l'objet global. **L'objet global est Window
dans l'environnement du navigateur et Global
dans l'environnement Node.js
. 🎜🎜Par exemple, dans le code suivant, en mode non strict, this
pointe tous vers l'objet global. 🎜rrreee🎜Le résultat de l'exécution en mode non strict est : 🎜🎜🎜🎜在严格模式下,执行同样的代码进行对比。记住要一次性将所有代码复制粘贴到控制台中,才能运行在严格模式下(因为第一行 "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
。
2. 以下箭头函数中 this 指向谁呢?
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视频教程
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!