Maison  >  Article  >  interface Web  >  Suivez-moi pour apprendre les appels de fonctions javascript et les compétences du constructeur en matière d'appels_javascript

Suivez-moi pour apprendre les appels de fonctions javascript et les compétences du constructeur en matière d'appels_javascript

WBOY
WBOYoriginal
2016-05-16 15:32:171230parcourir

1. Appel de fonction
La fonction est certainement la chose la plus importante en JavaScript. En JavaScript, Function assume les fonctions de procédures, de méthodes, de constructeurs et même de classes et de modules.

Dans la programmation orientée objet, les fonctions, les méthodes et le constructeur de classe sont souvent trois choses différentes, implémentées par des syntaxes différentes. Mais en JavaScript, ces trois concepts sont implémentés par des fonctions, à travers trois modes différents.

Le mode d'utilisation le plus simple est l'appel de fonction :

function hello(username) { 
  return "hello, " + username; 
} 
hello("Keyser Söze"); // "hello, Keyser Söze" 

2. Appel de méthode

Le concept des méthodes en JavaScript est que l'attribut d'un objet est une fonction : c'est la même fonction, mais elle est différente après l'avoir assignée à un membre d'un objet. Après avoir attribué une fonction à un membre d’un objet, on ne l’appelle plus fonction, mais méthode.

var obj = { 
  hello: function() { 
    return "hello, " + this.username; 
  }, 
  username: "Hans Gruber" 
}; 
obj.hello(); // "hello, Hans Gruber" 

Le vrai comportement est que l'appel lui-même détermine à quel objet il sera lié, c'est-à-dire :
obj1.hello() le liera à obj1, et obj2.hello() le liera à obj2. Rappelez-vous une phrase, celui qui appelle, cela indiquera à qui

En raison de cette règle contraignante, l'utilisation suivante est également possible :

function hello() { 
  return "hello, " + this.username; 
} 

var obj1 = { 
  hello: hello, 
  username: "Gordon Gekko" 
}; 
obj1.hello(); // "hello, Gordon Gekko" 

var obj2 = { 
  hello: hello, 
  username: "Biff Tannen" 
};_ 
obj2.hello(); // "hello, Biff Tannen" 

Cependant, dans une fonction ordinaire, comme la fonction hello ci-dessus, utiliser le mot-clé this n'est pas un bon moyen. Lorsqu'il est appelé directement, le pointage de this devient un problème. Dans ce cas, il s'agit souvent de l'objet global (GlobalObject), qui est généralement l'objet fenêtre des navigateurs.
Et ce comportement est incertain et dénué de sens.

Donc dans la norme ES5, si le mode strict est utilisé, celui-ci sera défini sur undefined :

function hello() { 
  "use strict"; 
  return "hello, " + this.username; 
} 
hello(); // error: cannot read property "username" of undefined 

L'approche ci-dessus consiste à exposer plus rapidement les erreurs potentielles et à éviter les erreurs de fonctionnement et les bogues difficiles à trouver.
La différence entre les appels de fonction ordinaires et les appels de méthode sera claire en regardant cet exemple.

var func = function() {
  alert(this);
};
var o = {};
o.fn = func;
// 比较
alert(o.fn === func);//true
// 调用
func();//[object Window]
o.fn();//[object Object]

Le résultat ici est que les deux fonctions sont les mêmes, donc le résultat imprimé est vrai. Cependant, comme les appels des deux fonctions sont différents, l'appel de func imprime [object Window], tandis que le résultat d'impression de o.fn est [object Object].

Voici la différence entre l'appel de fonction et l'appel de méthode. Dans l'appel de fonction, cela fait spécifiquement référence à la fenêtre d'objet globale, tandis que dans la méthode, cela fait spécifiquement référence à l'objet actuel, c'est-à-dire que ceci dans o.fn fait référence à l'objet. o.

3. Appeler le constructeur

Le troisième mode d'utilisation de la fonction est de l'utiliser comme constructeur :

this

dans le constructeur

Nous devons analyser le processus de création d'un objet pour en connaître la signification, comme le montre le code suivant :

 var Person = function() {
  this.name = "小平果";
 };
 var p = new Person();

La fonction Personne est d'abord définie ici. Analysons l'ensemble de l'exécution :

  • Lorsque le programme exécute cette phrase, il n'exécutera pas le corps de la fonction, donc l'interpréteur JavaScript ne connaît pas le contenu de cette fonction.
  • Ensuite, exécutez le nouveau mot-clé pour créer l'objet. L'interpréteur alloue de la mémoire, obtient une référence à l'objet et transmet la référence au nouvel objet à la fonction.
  • Ensuite, exécutez la fonction et transmettez-lui la référence d'objet transmise. En d'autres termes, dans la méthode constructeur, il s'agit de l'objet qui vient d'être créé par new.
  • Ensuite, ajoutez des membres à ceci, c'est-à-dire ajoutez des membres à l'objet.
  • Enfin, la fonction se termine, renvoie ceci et le remet à la variable de gauche.

Après avoir analysé l'exécution du constructeur, nous pouvons obtenir que ceci dans le constructeur est l'objet actuel.

retour en constructeur

La signification du retour dans le constructeur a changé. Premièrement, si dans le constructeur, si un objet est renvoyé, alors la signification d'origine est conservée si le retour est un non-objet, comme un nombre, un booléen et. chaîne, alors le retour est ceci, s'il n'y a pas d'instruction return, alors ceci est également renvoyé. Regardez le code suivant :

.

 // 返回一个对象的 return
 var ctr = function() {
  this.name = "赵晓虎";
  return {
  name:"牛亮亮"
  };
 };
 // 创建对象
 var p = new ctr();
 // 访问name属性
 alert(p.name);

 //执行代码,这里打印的结果是"牛亮亮". 因为构造方法中返回的是一个对象,那么保留return的意义,返回内容为return后面的对象. 再看下面代码:

 // 定义返回非对象数据的构造器
 var ctr = function() {
  this.name = "赵晓虎";
  return "牛亮亮";
 };
 // 创建对象
 var p = new ctr();
 // 使用
 alert(p);
 alert(p.name);

Le résultat de l'exécution du code est que la fenêtre contextuelle imprime d'abord [object Object], puis imprime "Zhao Xiaohu". Parce que le retour ici est une chaîne, qui appartient au type de base, puis l'instruction return. ici n'est pas valide et l'objet this est renvoyé. Par conséquent, le premier imprime [objet Objet] mais le second n'imprime pas undéfini.

function User(name, passwordHash) { 
  this.name = name; 
  this.passwordHash = passwordHash; 
} 
var u = new User("sfalken", 
  "0ef33ae791068ec64b502d6cb0191387"); 
u.name; // "sfalken" 

Utilisez la nouvelle clé pour appeler la fonction en tant que constructeur. Contrairement aux appels de fonction et de méthode, le constructeur transmettra un nouvel objet et le liera à celui-ci, puis renverra l'objet comme valeur de retour du constructeur. La fonction de la fonction constructeur elle-même est d'initialiser l'objet.

Une erreur courante dans l'appel du constructeur

J'ai défini avec plaisir le constructeur suivant :

var Coder = function( nick ){ 
this.nick = nick; 
}; 

Que se passe-t-il après avoir défini le constructeur ? C'est vrai, instanciez-le rapidement :

var coder = Coder( 'casper' ); 

Comment s'appelle ce frère codeur ? Imprimez-le vite :

console.log( coder.nick ); //undefined 
= =b 竟然是undefined!!再回过头看看实例化的那个语句,不难发现问题出在哪里:少了个new 
var coder = Coder( 'casper' ); //当作普通的函数来调用,故内部的this指针其实指向window对象 
console.log( window.nick); //输出:casper 
var coder = new Coder( 'casper' ); //加上new,一切皆不同,this正确地指向了当前创建的实例 
console.log( coder.nick ); //输出:casper 

这样的错误貌似挺低级的,但出现的概率挺高的,肿么去避免或减少这种情况的发生呢?
可以在内部实现里面动下手脚:

var Coder = function( nick ){ 
  if( !(this instanceof Coder) ){ 
    return new Coder( nick ); 
  } 
    this.nick = nick; 
}; 

其实很简单,实例化的时候,内部判断下,当前this指向的对象的类型即可,如果非当前构造函数的类型,强制重新调用一遍构造函数。
突然觉得Coder这名字不够洋气?想用Hacker,好吧,我改。。。数了下,一共有三处要改,这不科学,有没有办法只把构造函数的名字改了就行?
当然有:

var Coder = function( nick ){ 
  if( !(this instanceof arguments.callee) ){ 
    return new arguments.callee( nick ); 
  } 
  this.nick = nick; 
}; 

tips:据说在ES 5的严格模式下面arguments.callee会被禁用,不过仅当ES 5普及同时你指定了要使用严格模式,否则还是可以用的发散下思维。

以上就是本文的全部内容,希望对大家学习函数调用、方法调用和构造函数调用有所帮助。

Déclaration:
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