Maison >interface Web >js tutoriel >Un article expliquant le problème de ce pointage en js (avec code)

Un article expliquant le problème de ce pointage en js (avec code)

奋力向前
奋力向前avant
2021-09-17 10:16:281724parcourir

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.

Un article expliquant le problème de ce pointage en js (avec code)

Ce problème de pointage en JS

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指向了。

接下来按照口诀顺序对它们进行详解,文中示例代码都运行在ChromeConsole控制台中。

文末有精心准备的练习题,用于检验学习成果,别忘了试试~

1. 箭头函数

箭头函数排在第一个是因为它的this不会被改变,所以只要当前函数是箭头函数,那么就不用再看其他规则了。

箭头函数的this是在创建它时外层this的指向。这里的重点有两个:

1、创建箭头函数时,就已经确定了它的this指向。

2、箭头函数内的this指向外层的this

所以要知道箭头函数的this就得先知道外层this的指向,需要继续在外层应用七步口诀。

2. new

当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象。

读者可能会有疑问,“如果使用new关键调用箭头函数,是不是箭头函数的this就会被修改呢?”。

我们在控制台试一下。

func = () => {} 
new func() // throw error

Un article expliquant le problème de ce pointage en js (avec code)

从控制台中可以看出,箭头函数不能当做构造函数,所以不能与new一起执行。

3. bind

bind 是指 Function.prototype.bind() 详细地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

多次 bind 时只认第一次 bind 的值

易错点

function func() {
  console.log(this)
}

func.bind(1).bind(2)() // 1

箭头函数中 this 不会被修改

func = () => {
  // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
  console.log(this)
}

func.bind(1)() // Window,口诀 1 优先

bind 与 new

易错点

function func() {
  console.log(this, this.__proto__ === func.prototype)
}

boundFunc = func.bind(1)
new boundFunc() // Object true,口诀 2 优先

4. apply 和 call

apply()和 call()的第一个参数都是this,区别在于通过apply调用时实参是放到数组中的,而通过call调用时实参是逗号分隔的。

箭头函数中 this 不会被修改

易错点

func = () => {
  // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
  console.log(this)
}

func.apply(1) // Window,口诀 1 优先

bind 函数中 this 不会被修改

易错点

function func() {
  console.log(this)
}

boundFunc = func.bind(1)
boundFunc.apply(2) // 1,口诀 3 优先

5. 欧比届点(obj.)

function func() {
  console.log(this.x)
}

obj = { x: 1 }
obj.func = func
obj.func() // 1

这里就不用代码例证箭头函数和 bind 函数的优先级更高了,有兴趣可自行尝试吧。

6. 直接调用

在函数不满足前面的场景,被直接调用时,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 })()

7. 不在函数里

不在函数中的场景,可分为浏览器的<script></script>标签里,或Node.js的模块文件里。

1、在<script></script>标签里,this指向Window

2、在Node.js的模块文件里,this指向Module的默认导出对象,也就是module.exports

非严格模式

严格模式是在ES5提出的。在ES5规范之前,也就是非严格模式下,this不能是undefinednull。所以**在非严格模式下,通过上面七步口诀,如果得出this指向是undefinednull,那么this会指向全局对象。**在浏览器环境中全局对象是Window,在Node.js环境中是Global

例如下面的代码,在非严格模式下,this

Lisez d'abord la formule : fonction flèche, nouveau, liaison, application et appel, point Obj (obj.), appel direct, pas dans une fonction.

Selon l'ordre de la formule, tant que l'un des scénarios précédents est rempli, vous pouvez déterminer où pointe this.

Un article expliquant le problème de ce pointage en js (avec code) 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.

🎜Il y a des exercices soigneusement préparés à la fin de l'article pour tester vos résultats d'apprentissage, n'oubliez pas d'essayer~🎜🎜1 Fonction flèche🎜🎜La fonction flèche est classée première car c'est 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()
🎜WeChat capture d'écran_20210917095948.png🎜 🎜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 apply Les paramètres réels sont placés dans le tableau, et lorsqu'ils sont appelés via <code>call, les paramètres réels sont séparés par des virgules. 🎜🎜Ceci dans la fonction flèche ne sera pas modifié🎜🎜Sujet aux erreurs🎜
// 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
🎜🎜Le scénario de ne pas être dans une fonction peut être divisé en la balise <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()

严格模式下执行结果为:

Un article expliquant le problème de ce pointage en js (avec code)

七步口诀在严格模式下和非严格模式下都是完备的,只是在非严格模式下nullundefined会被转换为全局对象。所以我没有将这点列入口诀中。

做题复习

先背诵口诀再做题,“箭头函数、newbindapplycall、欧比届点(obj.)、直接调用、不在函数里”。

1. 下面代码执行后,func.count 值为多少?

function func(num) {
  this.count++
}

func.count = 0
func(1)

答案

func.count值为 0。

按照口诀,func()调用时属于第 6 类「直接调用」。在非严格模式下,this指向全局对象。thisfunc 一点关系都没有,所以 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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer