Maison > interface Web > js tutoriel > le corps du texte

Suivez-moi pour apprendre ce mot-clé de compétences javascript_javascript

WBOY
Libérer: 2016-05-16 15:31:09
original
956 Les gens l'ont consulté

Cet article ne traite que de ce problème. Après avoir lu cet article, si les lecteurs peuvent répondre correctement à la question Qu'est-ce que c'est en JavaScript, en tant qu'auteur, je penserai que cela vaut la peine de consacrer autant d'efforts à écrire un tel article.

Nous devons retenir une phrase : cela pointe toujours vers l'objet où la fonction est exécutée ! plutôt que l'objet dans lequel la fonction a été créée. Autrement dit : celui qui appelle désigne qui. Rappelez-vous…

Cet article analysera où se trouve cet objet dans trois situations.
1. ceci
dans les fonctions ordinaires Quel que soit l'endroit où il se trouve, la première priorité est de trouver l'emplacement lorsque la fonction est en cours d'exécution.

 var name="全局";
 function getName(){
   var name="局部";
   return this.name;
 };
 alert(getName());
Copier après la connexion

Lorsque cela apparaît dans la fonction getName de l'environnement global, l'emplacement d'exécution de la fonction getName est

alert(getName());
Copier après la connexion

Évidemment, l'objet où se trouve la fonction getName est l'objet global, c'est-à-dire window, donc sa maison doit être dans window. À ce stade, this pointe vers l'objet window, donc le this.name renvoyé par getName est en fait window.name, donc l'alerte est « globale » !

Alors, quand cela n'apparaît pas dans la fonction de l'environnement global, mais apparaît dans la fonction de l'environnement local, où va-t-il tomber ?

 var name="全局";
 var xpg={
   name:"局部",
   getName:function(){
     return this.name;
   }
 };
 alert(xpg.getName());
Copier après la connexion

La fonction getName dans laquelle cela se trouve n'est pas dans l'environnement global, mais dans l'environnement xpg. Peu importe où il se trouve, vous devez trouver l'emplacement lorsque la fonction est en cours d'exécution. La position de la fonction getName lorsqu'elle est en cours d'exécution à ce moment

alert(xpg.getName());
Copier après la connexion

Évidemment, l'objet où se trouve la fonction getName est xpg, donc la maison de this doit être dans xpg, c'est-à-dire qu'elle pointe vers l'objet xpg. Ensuite, le this.name renvoyé par getName est en fait xpg.name, donc l'alerte apparaît comme "partielle" !

Donnez un exemple à consolider :

var someone = {
  name: "Bob",
  showName: function(){
    alert(this.name);
  }
};

var other = {
  name: "Tom",
  showName: someone.showName
}

other.showName();  //Tom

Copier après la connexion

Bien que le mot-clé this soit déclaré dans Someone.showName, il s'agit de other.showName lors de l'exécution, cela pointe donc vers l'objet actuel de la fonction other.showName, qui est other, donc l'alerte finale est other.name.

2. ceci en clôture

La fermeture est aussi un fauteur de troubles. Cet article n'entrera pas dans les détails pour le moment. En bref : la soi-disant fermeture consiste à créer une autre fonction à l'intérieur d'une fonction, et la fonction interne accède aux variables externes.
Le fils prodigue se mêle à la fermeture voyou, ce qui montre qu'il n'y aura jamais de paix !

 var name="全局";
 var xpg={
   name:"局部",
   getName:function(){
     return function(){
       return this.name;
     };
   }
 };
 alert(xpg.getName()());
Copier après la connexion

En ce moment, c'est évidemment en difficulté. C'est en fait dans la fonction anonyme de la fonction getName, et la fonction anonyme appelle le nom de la variable, formant ainsi une fermeture, c'est-à-dire que c'est dans la fermeture.
Peu importe où il se trouve, vous devez trouver l'emplacement lorsque la fonction est en cours d'exécution. Pour le moment, il ne peut pas être jugé sur la base de la position d'exécution de la fonction getName, mais sur la base de la position d'exécution de la fonction anonyme.

function (){
  return this.name;
};

Copier après la connexion

Évidemment, l'objet où se trouve la fonction anonyme est window, donc la maison de this doit être dans window, alors le this.name renvoyé par la fonction anonyme est en fait window.name, donc ce qui sort de l'alerte est le "mondial"!

Alors, comment faire ça en xpg dans la fermeture ? —Cache ceci

 var name="全局";
 var xpg={
   name:"局部",
   getName:function(){
     var that=this;
     return function(){
       return that.name;
     };
   }
 };
 alert(xpg.getName()());
Copier après la connexion

Définissez that=this dans la fonction getName. À l'heure actuelle, la fonction getName est exécutée sur

.
alert(xpg.getName());
Copier après la connexion

Ensuite, cela pointe vers l'objet xpg, donc cela pointe également vers l'objet xpg. Si that.name est renvoyé dans la fonction anonyme de la fermeture, le that.name renvoyé à ce moment est en fait xpg.name, donc le "local" peut être alerté !

3. Le nouveau mot-clé crée un nouvel objet

Ceci dans le constructeur après le nouveau mot-clé pointe vers le nouvel objet construit avec le constructeur :

function Person(__name){
  this.name = __name;    //这个this指向用该构造函数构造的新对象,这个例子是Bob对象
}
Person.prototype.show = function(){
  alert(this.name);  //this 指向Person,this.name = Person.name;
}

var Bob = new Person("Bob");
Bob.show();    //Bob

Copier après la connexion

4. appelez-le et postulez

Les seuls qui peuvent gérer cela en JavaScript sont d'appeler et de postuler.
appeler et postuler sont comme les parents de celui-ci, ils vivront partout où ils le laisseront vivre, et ils doivent obéir ! Lorsqu'il n'y a pas de paramètres, l'objet actuel est window

var name="全局";
var xpg={
  name:"局部"
};
function getName(){
  alert(this.name);
}
getName(xpg);
getName.call(xpg);
getName.call();
Copier après la connexion

Où cela se trouve dans la fonction getName. Peu importe où il se trouve, vous devez trouver l'emplacement lorsque la fonction est en cours d'exécution. La position de la fonction getName lorsqu'elle est en cours d'exécution à ce moment

getName(xpg);
Copier après la connexion

Évidemment, l'objet où se trouve la fonction getName est window, donc la maison de this doit être dans la fenêtre, c'est-à-dire pointer vers l'objet window. Ensuite, le this.name renvoyé par getName est en fait window.name, donc l'alerte sort comme "globale" !

Alors, il est temps d’appeler et de postuler, car celui-ci doit écouter leur commandement !
getName.call(xpg);
Parmi eux, call spécifie que la maison de this est l'objet xpg, car celui-ci est forcé de s'installer uniquement dans xpg, alors cela pointe vers l'objet xpg à ce moment-là, this.name est en fait xpg.name, donc l'alerte sort comme "local" !

5. ceci en évaluation

Pour la fonction eval, il semble que l'objet courant ne soit pas spécifié lors de son exécution, mais en fait cela ne pointe pas vers la fenêtre, car la portée lorsque la fonction est exécutée est la portée actuelle, ce qui est équivalent à remplir le code à l'intérieur de cette ligne. L'exemple suivant illustre ce problème :

var name = "window";

var Bob = {
  name: "Bob",
  showName: function(){
    eval("alert(this.name)");
  }
};

Bob.showName();  //Bob

Copier après la connexion

6、没有明确的当前对象时的this

当没有明确的执行时的当前对象时,this指向全局对象window。
例如对于全局变量引用的函数上我们有:

var name = "Tom";

var Bob = {
  name: "Bob",
  show: function(){
    alert(this.name);
  }
}

var show = Bob.show;
show();  //Tom

Copier après la connexion

你可能也能理解成show是window对象下的方法,所以执行时的当前对象时window。但局部变量引用的函数上,却无法这么解释:

var name = "window";

var Bob = {
  name: "Bob",
  showName: function(){
    alert(this.name);
  }
};

var Tom = {
  name: "Tom",
  showName: function(){
    var fun = Bob.showName;
    fun();
  }
};

Tom.showName();  //window

Copier après la connexion

在浏览器中setTimeout、setInterval和匿名函数执行时的当前对象是全局对象window,这条我们可以看成是上一条的一个特殊情况。

var name = "Bob"; 
var nameObj ={ 
   name : "Tom", 
   showName : function(){ 
     alert(this.name); 
   }, 
   waitShowName : function(){ 
     setTimeout(this.showName, 1000); 
   } 
 }; 

 nameObj.waitShowName();

Copier après la connexion

所以在运行this.showName的时候,this指向了window,所以最后显示了window.name。

7、dom事件中的this

(1)你可以直接在dom元素中使用

<input id="btnTest" type="button" value="提交" onclick="alert(this.value))" />
Copier après la connexion

分析:对于dom元素的一个onclick(或其他如onblur等)属性,它为所属的html元素所拥有,直接在它触发的函数里写this,this应该指向该html元素。

(2)给dom元素注册js函数
a、不正确的方式

<script type="text/javascript">
 function thisTest(){
 alert(this.value); // 弹出undefined, this在这里指向&#63;&#63;
}
</script>
<input id="btnTest" type="button" value="提交" onclick="thisTest()" />
Copier après la connexion

分析:onclick事件直接调用thisTest函数,程序就会弹出undefined。因为thisTest函数是在window对象中定义的,
所以thisTest的拥有者(作用域)是window,thisTest的this也是window。而window是没有value属性的,所以就报错了。
b、正确的方式

<input id="btnTest" type="button" value="提交" />

<script type="text/javascript">
 function thisTest(){
 alert(this.value); 
}
document.getElementById("btnTest").onclick=thisTest; //给button的onclick事件注册一个函数
</script>

Copier après la connexion

分析:在前面的示例中,thisTest函数定义在全局作用域(这里就是window对象),所以this指代的是当前的window对象。而通过document.getElementById(“btnTest”).onclick=thisTest;这样的形式,其实是将btnTest的onclick属性设置为thisTest函数的一个副本,在btnTest的onclick属性的函数作用域内,this归btnTest所有,this也就指向了btnTest。其实如果有多个dom元素要注册该事件,我们可以利用不同的dom元素id,用下面的方式实现:

document.getElementById("domID").onclick=thisTest; //给button的onclick事件注册一个函数。
Copier après la connexion

因为多个不同的HTML元素虽然创建了不同的函数副本,但每个副本的拥有者都是相对应的HTML元素,各自的this也都指向它们的拥有者,不会造成混乱。
为了验证上述说法,我们改进一下代码,让button直接弹出它们对应的触发函数:

<input id="btnTest1" type="button" value="提交1" onclick="thisTest()" />
<input id="btnTest2" type="button" value="提交2" />

<script type="text/javascript">
function thisTest(){
this.value="提交中";
}
var btn=document.getElementById("btnTest1");
alert(btn.onclick); //第一个按钮函数

var btnOther=document.getElementById("btnTest2");
btnOther.onclick=thisTest;
alert(btnOther.onclick); //第二个按钮函数
</script>
其弹出的结果是:

//第一个按钮
function onclick(){
 thisTest()
}

//第二个按钮
function thisTest(){
 this.value="提交中";
}

Copier après la connexion

从上面的结果你一定理解的更透彻了。
By the way,每新建一个函数的副本,程序就会为这个函数副本分配一定的内存。而实际应用中,大多数函数并不一定会被调用,于是这部分内存就被白白浪费了。所以我们通常都这么写:

<input id="btnTest1" type="button" value="提交1" onclick="thisTest(this)" />
<input id="btnTest2" type="button" value="提交2" onclick="thisTest(this)" />
<input id="btnTest3" type="button" value="提交3" onclick="thisTest(this)" />
<input id="btnTest4" type="button" value="提交4" onclick="thisTest(this)" />

<script type="text/javascript">
 function thisTest(obj){
 alert(obj.value); 
}
</script>

Copier après la connexion

这是因为我们使用了函数引用的方式,程序就只会给函数的本体分配内存,而引用只分配指针。这样写一个函数,调用的地方给它分配一个(指针)引用,这样效率就高很多。当然,如果你觉得这样注册事件不能兼容多种浏览器,可以写下面的注册事件的通用脚本:

//js事件 添加 EventUtil.addEvent(dom元素,事件名称,事件触发的函数名) 移除EventUtil.removeEvent(dom元素,事件名称,事件触发的函数名)
var EventUtil = new eventManager();

//js事件通用管理器 dom元素 添加或者移除事件
function eventManager() {
  //添加事件
  //oDomElement:dom元素,如按钮,文本,document等; ****** oEventType:事件名称(如:click,如果是ie浏览器,自动将click转换为onclick);****** oFunc:事件触发的函数名
  this.addEvent = function(oDomElement, oEventType, oFunc) {
    //ie
    if (oDomElement.attachEvent) {
      oDomElement.attachEvent("on" + oEventType, oFunc);
    }
    //ff,opera,safari等
    else if (oDomElement.addEventListener) {
      oDomElement.addEventListener(oEventType, oFunc, false);
    }
    //其他
    else {
      oDomElement["on" + oEventType] = oFunc;
    }
  }

  this.removeEvent = function(oDomElement, oEventType, oFunc) {
    //ie
    if (oDomElement.detachEvent) {
      oDomElement.detachEvent("on" + oEventType, oFunc);
    }
    //ff,opera,safari等
    else if (oDomElement.removeEventListener) {
      oDomElement.removeEventListener(oEventType, oFunc, false);
    }
    //其他
    else {
      oDomElement["on" + oEventType] = null;
    }
  }
}

Copier après la connexion

正像注释写的那样,要注册dom元素事件,用EventUtil.addEvent(dom元素,事件名称,事件触发的函数名)即可, 移除时可以这样写:EventUtil.removeEvent(dom元素,事件名称,事件触发的函数名),这是题外话,不说了。

 以上就是本文的全部内容,希望通过这篇文章大家更加了解javascript的this关键字,大家共同进步。

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal