Maison  >  Article  >  interface Web  >  Un article pour comprendre ce problème de pointage en JavaScript

Un article pour comprendre ce problème de pointage en JavaScript

WBOY
WBOYavant
2022-11-30 16:04:313050parcourir

Cet article vous apporte des connaissances pertinentes sur JavaScript, qui présente principalement les problèmes connexes signalés par ceci. Cela signifie "ceci, actuel" et est une variable de pointeur qui pointe dynamiquement vers la fonction actuelle. . J'espère que cela sera utile à tout le monde.

Un article pour comprendre ce problème de pointage en JavaScript

[Recommandations associées : Tutoriel vidéo JavaScript, front-end web]

Le concept de ceci :

  • En js, cela signifie "ceci ; actuel", est un pointeur variable de type, qui pointe dynamiquement vers l’environnement d’exécution de la fonction actuelle.

  • Lorsque la même fonction est appelée dans différents scénarios, le pointeur de celle-ci peut également changer, mais il pointera toujours vers le véritable appelant de la fonction dans laquelle elle se trouve ; s'il n'y a pas d'appelant, il pointera ; à la fenêtre des objets globaux.

Fonction ordinaire : À ce propos, celui qui l'appelle pointe vers celui qui l'appelle. S'il n'y a pas d'appelant, il pointe vers la fenêtre de l'objet global.
Fonction flèche : cette fonction flèche pointe vers l'objet utilisé dans la portée de la fonction.

1. Ceci dans l'environnement global pointe vers

Dans le scope global , cela pointe toujours vers la fenêtre de l'objet global, qu'elle soit ou non en mode strict !

congsole.log()La méthode d'écriture complète est window.console.log(), window peut être omise, window est appelée méthode console.log(), donc cela pointe vers la fenêtre à ce moment-là. congsole.log()完整的写法是window.console.log(),window可以省略,window调用了console.log()方法,所以此时this指向window。

二、函数内的this

  • 普通函数内的this分为两种情况,严格模式下和非严格模式下。
1. 严格模式下:

直接test()调用函数,this指向undefined,window.test()调用函数this指向window。因此,在严格模式下, 我们对代码的的调用必须严格的写出被调用的函数的对象,不可以有省略或者说简写。

2. 非严格模式下:

非严格模式下,通过test()和window.test()调用函数对象,this都指向window。

三、对象中的this

对象内部方法的this指向调用这些方法的对象,也就是谁调用就指向谁

1. 一层对象:

调用obj.skill()方法,返回值为蒙犽,说明此时this指向obj。

2. 二层对象:

调用skill2()方法的顺序为,obj.obj2.skill2() ,返回值为鲁班,说明skill2()方法中的this指向obj2。

总结:

  • 函数的定义位置不影响其this指向,this指向只和调用函数的对象有关

  • 多层嵌套的对象,内部方法的this指向离被调用函数最近的对象

四、箭头函数中的this

箭头函数:this指向于函数作用域所用的对象。

Exemple 1 :

  • déclare la variable globale Obj, et celle-ci pointe vers l'objet dans la portée globale où se trouve la fonction flèche, c'est-à-dire l'objet indow.

Exemple 2 :

  • Étant donné que la fonction show est une fonction de flèche, elle ne peut pas la lier par elle-même, elle recherche donc sa portée de niveau supérieur. Si la portée parent est toujours une fonction fléchée, recherchez à nouveau, couche par couche, jusqu'à ce que vous atteigniez ce point.

  • window.show()La valeur de retour est window, donc cela pointe vers window à ce moment window.show()返回值是window,所以this此时指向window;

  • window.obj.show(),obj是对象,非箭头函数,所以找到这里就停止了,this绑定到obj上。window调用obj,所以obj中的this也指向window。

五、构造函数中的this

构造函数中的this是指向实例。

由上图可以看出,构造函数中的this指向构造函数下创建的实例

、原型链中的this

this这个值在一个继承机制中,仍然是指向它原本属于的对象,而不是从原型链上找到它时,它所属于的对象。

七、改变this指向的方法

1. call()

  • call(a, b, c)方法接收三个参数,第一个是this指向,第二个,三个是传递给函数的实参,可以是数字,字符串,数组等类型的数据类型都可以。

示例:

//定义函数function fn(n1,n2){
   console.log(this);  
   console.log(n1,n2)}//调用call()方法fn.call();//=>this:window;let obj = {fn:fn};fn.call(obj);
   //=>this:obj;n1,n2:undefinedfn.call(1,2);//=>this: 1;n1=2,n2=undefined;fn.call(obj,1,2);//=>this: obj;n1=1,n2=2;
   //Call方法的几个特殊属性
   //非严格模式下fn.call(undefined);//this=>windowfn.call(null);//this=>window
   //严格模式下"use strict"fn.call(undefined);//this=>undefinedfn.call(null);//this=>null
2. apply()
  • apply(a, [b])和call基本上一致,唯一区别在于传参方式,apply把需要传递给fn()的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn()一个个的传递。

  • //call()的传参方式
    fn.call(obj, 1, 2);//apply()的传参方式fn.apply(obj, [1, 2]);

示例:

//apply方法的使用和call方法基本相同,唯一的区别是,apply方法传参要求是数组类型的,数组内可以任意形式的数据
function fn (n1,n2){
    console.log(this);
    console.log(n1,n2)
    console.log(arguments)}let obj = {fn:fn};
    //调用apply()方法
    fn.applay(abj,[1,2]);fn.applay(abj,1,2);
    //报错
    fn.applay(abj,[11,'apply',{a:123}]);
    //注意第二个参数必须是数组,否则会报错
3. bind()
  • bind(a, b, c):语法和call一模一样,区别在于立即执行还是等待执行,bind不兼容IE6~8

  • bind与call的唯一区别就是call直接改变函数test的指向,而bind生成了一个新函数test2()

  • window.obj.show(), obj ; > est un objet, une fonction non-flèche, donc il s'arrête lorsqu'il trouve ce point, et cela est lié à obj.
  • Window appelle obj, donc ceci dans obj pointe également vers window.

5. ceci dans le constructeur

dans le constructeur cela pointe vers l'instance.

    Comme vous pouvez le voir sur l'image ci-dessus Out,
  • this dans le constructeur pointe vers l'instance créée sous le constructeur
  • .

6, ceci dans la chaîne de prototypes

    cette valeur est toujours dans un mécanisme d'héritage
  • Pointe vers l'objet
  • auquel il appartenait à l'origine, plutôt que l'objet auquel il appartenait lorsqu'il a été trouvé sur la chaîne prototype.
  • 7. Comment changer le point de ceci

    1. call()

    La méthode call(a, b, c) reçoit trois paramètres, le premier est pointé par ceci, le deuxième Un et trois sont les paramètres réels transmis à la fonction, qui peuvent être n'importe quel type de données tel que des nombres, des chaînes, des tableaux, etc.

    🎜Exemple : 🎜🎜
    //call()方法:改变fn中的this,并且把fn立即执行fn.call(obj, 1, 2); //bind()方法:改变fn中的this,fn并不执行fn.bind(obj, 1, 2);
    🎜2. apply()
    🎜🎜🎜apply(a, [b]) et appelez Fondamentalement pareil, la seule différence réside dans la méthode de transmission des paramètres. apply place les paramètres qui doivent être transmis à fn() dans un tableau (ou de type tableau) et les transmet. est écrit sous forme de tableau, mais cela équivaut également à passer fn() un par un. 🎜🎜🎜
    //bind和call方法调用形式类似,但是原理完全不同
    fn.call(obj,10,20);//=>fn先执行,将fn内的this指向obj,并且把参数10,20传递给fn
    
    fn.bind(obj,10,20)//bind是先将fn中的this指向obj,并且将参数10,20预先传递给fn,但是此时的fn并没有被执行,只有fn执行时this指向和传递参数才有作用
    fn.bind(obj,10,20);//=>不会有任何输出
    fn.bind(obj,10,20)();//=>调用后才会有输出
    
    //=>需求:点击box这个盒子的时候,需要执行fn,并且让fn中的this指向obj
    oBox.onclick=fn; //=>点击的时候执行了fn,但此时fn中的this是oBox
    
    oBox.onclick=fn.call(opp); //=>绑定事件的时候就已经把fn立即执行了(call本身就是立即执行函数),然后把fn执行的返回值绑定给事件
    
    oBox.onclick=fn.bind(opp);
    //=>fn.bind(opp):fn调取Function.prototype上的bind方法,执行这个/* 
     * function(){
     *     fn.call(opp);
     * }
     */
    oBox.onclick=function(){
       //=>this:oBox
        fn.call(opp);
    }
    🎜🎜🎜🎜Exemple : 🎜🎜rrreee
    🎜3. bind()
    🎜🎜🎜bind(a, b, c) h5> code> : La syntaxe est exactement la même que celle de call. La différence est de savoir s'il faut exécuter immédiatement ou attendre l'exécution. bind n'est pas compatible avec IE6~8🎜🎜🎜🎜La seule différence entre bind et call🎜 est cet appel direct. change le pointeur de la fonction test, tandis que 🎜bind🎜 est 🎜generated. Une nouvelle fonction 🎜<code>test2() a été ajoutée, qui a changé le pointeur. 🎜🎜🎜rrreee🎜🎜🎜🎜Exemple : 🎜🎜rrreee🎜🎜🎜Mêmes points : 🎜🎜🎜🎜call, apply et bind sont toutes des méthodes internes publiques des fonctions JS. Elles réinitialisent toutes le this de la fonction et modifient la fonction. lien d'exécution. 🎜🎜🎜🎜Différences : 🎜🎜🎜🎜bind consiste à créer une nouvelle fonction, tandis que call et aplay sont utilisés pour appeler des fonctions ; 🎜🎜call et apply ont la même fonction, sauf que les paramètres fournis par call pour la fonction sont répertoriés. un par un sort, et le paramètre fourni par apply pour la fonction est un tableau🎜🎜🎜🎜[Recommandations associées : 🎜Tutoriel vidéo JavaScript🎜, 🎜front-end web🎜]🎜

    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