Récemment,
SmartSpate a décidé de collecter des questions sur
JavaScript et d'y répondre. Le matériel, dont nous publions la traduction, contient un peu plus de deux douzaines de questions sur JavaScript et leurs réponses. La gamme de sujets traités ici est assez large. En particulier, il s'agit des fonctionnalités du langage, des problÚmes rencontrés par les programmeurs lors de l'écriture de code JS, du travail dans le navigateur et dans Node.js.

Question numéro 1. Héritage de prototype
Je me suis habitué aux cours «classiques», mais j'ai décidé d'apprendre JavaScript. J'ai un problÚme pour comprendre le modÚle prototype. Si possible, expliquez, sous forme de modÚles, la possibilité de créer des «classes» en JavaScript, parlez-nous des méthodes et propriétés fermées et ouvertes des classes. Je comprends que beaucoup de choses ont déjà été écrites à ce sujet et qu'en JavaScript, les méthodes et les propriétés des objets sont, par défaut, accessibles au public, mais j'aimerais bien comprendre tout cela. Comment l'héritage de prototype fonctionne-t-il en JavaScript?
â RĂ©pondre
L'hĂ©ritage classique n'est pas sans rappeler la façon dont les gens hĂ©ritent des gĂšnes de leurs ancĂȘtres. Les gens ont des capacitĂ©s de base communes, comme marcher et parler. De plus, chaque personne a des particularitĂ©s. Les gens ne peuvent pas changer ce qu'on peut appeler leur «classe», mais ils peuvent changer leurs propres «propriĂ©tĂ©s» dans certaines limites. Dans le mĂȘme temps, les grands-parents, les mĂšres et les pĂšres ne peuvent pas influencer les gĂšnes des enfants ou des petits-enfants au cours de leur vie. Donc, tout est arrangĂ© sur Terre, mais imaginons une autre planĂšte sur laquelle les mĂ©canismes d'hĂ©ritage fonctionnent d'une maniĂšre spĂ©ciale. Disons que certains organismes capables de mutations y utilisent les mĂ©canismes de «transmission tĂ©lĂ©pathique». Cela s'exprime dans le fait qu'ils peuvent modifier les informations gĂ©nĂ©tiques de leurs propres descendants au cours de leur vie.
Prenons l'exemple de l'hĂ©ritage sur cette Ă©trange planĂšte. L'objet PĂšre hĂ©rite des gĂšnes de l'objet Grand-pĂšre et l'objet Fils hĂ©rite des informations gĂ©nĂ©tiques du pĂšre. Chaque habitant de cette planĂšte peut librement muter et changer les gĂšnes de ses descendants. Par exemple, chez "Grand-pĂšre", la peau a une couleur verte. Ce signe est hĂ©ritĂ© du «PĂšre» et du «Fils». Soudain, "Grand-pĂšre" dĂ©cide qu'il est fatiguĂ© d'ĂȘtre vert. Maintenant, il veut ĂȘtre bleu et change la couleur de sa peau (en termes de JS - change le prototype de sa classe), passant "tĂ©lĂ©pathiquement" cette mutation au "PĂšre" et au "Fils". AprĂšs cela, le «pĂšre», croyant que le «grand-pĂšre» avait survĂ©cu Ă l'esprit, dĂ©cide de changer ses gĂšnes pour qu'il redevienne vert (c'est-Ă -dire qu'il change son propre prototype). Ces changements sont "tĂ©lĂ©pathiquement" transmis au "Fils". En consĂ©quence, le «PĂšre» et le «Fils» ont Ă nouveau la peau verte. Dans le mĂȘme temps, "Grand-pĂšre" est toujours bleu. Maintenant, peu importe ce qu'il fait avec sa couleur, cela n'affectera personne d'autre. Et tout cela est dĂ» au fait que le "PĂšre" a explicitement dĂ©fini la couleur de sa peau dans son "prototype", et le "Fils" hĂ©rite de cette couleur. Puis le "Fils" pense de cette façon: "Je vais devenir noir. Et que mes descendants hĂ©ritent de la couleur de mon pĂšre. » Pour ce faire, il modifie sa propre propriĂ©tĂ© (et non la propriĂ©tĂ© de son prototype) de telle maniĂšre que sa propriĂ©tĂ© affecterait sa couleur, mais n'affecterait pas ses descendants. Nous exprimons tout cela sous forme de code:
var Grandfather = function () {};
Question numéro 2. Créer des objets
Si vous créez de nouvelles instances d'objets à l'aide du
new
mot clé, comment pouvez-vous vous protéger contre les erreurs? Voici comment je travaille habituellement:
- Je construis toujours des fonctions constructeurs pour qu'elles commencent par une majuscule.
- Je vérifie l'exactitude de l'opération en utilisant la construction
this instanceof Function_Name
(j'essaie de ne pas utiliser la construction du type this instanceof arguments.callee
pour des raisons de performances). - Cette approche est similaire à la précédente, mais la comparaison est faite avec
window
, car je n'aime pas coder en dur les noms des entités et je n'ai pas besoin d'écrire du code pour des environnements autres que le navigateur.
Quel est le modÚle le plus pratique pour créer des objets?
â RĂ©pondre
Il est préférable, à la fois sur le plan idéologique et sur la base de la familiarité de cette méthode, de créer des objets à l'aide du
new
mot clé. Dans ce cas, les fonctions constructeurs doivent recevoir des noms commençant par une majuscule.
Je préfÚre m'en tenir aux rÚgles et ne pas effectuer
this
vérifications supplémentaires sur les constructeurs. Si le constructeur est appelé sans
new
et que le travail commence dans la portĂ©e globale, cela peut ĂȘtre comparĂ© à «l'auto-tromperie». Dans le mĂȘme temps, je ne recommande en aucun cas de gĂ©rer les situations dans les concepteurs oĂč elles sont appelĂ©es sans le
new
mot clé. Par exemple, cela peut ressembler à ceci: si le constructeur est appelé sans
new
, alors, de toute façon, un nouvel objet est créé et retourné. Cette approche est idéologiquement incorrecte et conduit à des erreurs.
Voici un exemple de travail avec un constructeur.
var Obj = function () { "use strict"; this.pew = 100; };
Il vaut mieux ne pas utiliser le
new
mot-clĂ© pour les mĂ©thodes d'usine et pour les cas oĂč il n'y a pas besoin de constructeur, quand il sera plus pratique de crĂ©er un objet en utilisant un objet littĂ©ral. Supposons que le code constructeur indiquĂ© dans l'exemple suivant soit explicitement redondant:
Si, mĂȘme pour crĂ©er un petit objet, vous avez toujours besoin d'un constructeur, il vaut mieux le faire:
var Obj = function () { "use strict"; this.pew = 100; };
Ici, comme indiqué ci-dessus, du fait que le constructeur fonctionne en mode strict, une erreur se produit lors de son appel sans
new
.
Question numéro 3. Interception des clics de souris
Comment, en utilisant JavaScript, savoir sur quel bouton de la souris on clique?
â RĂ©pondre
Un clic sur les boutons de la souris génÚre des
mousedown
souris et de
mouseup
. Dans ce cas, l'événement
click
est généré uniquement par le bouton gauche de la souris. Dans le gestionnaire d'événements, vous devez vérifier le code situé dans la propriété
event.button
afin de savoir quel bouton est enfoncé (0 - gauche, 1 - milieu, 2 - droite). Cependant, dans IE, tout semble un peu différent. Prenons un exemple:
var button = document.getElementById ('button'),
La bibliothÚque jQuery prend en compte cette fonctionnalité IE, donc lorsque vous l'utilisez dans n'importe quel navigateur, vérifiez simplement la valeur de la propriété
event.which
au lieu de
event.button
avec
event.button
:
$('button').mousedown(function (event) { alert(['Left', 'Middle', 'Right'][event.which]); });
Question numéro 4. Interception de frappes sur les touches du clavier
Est-il possible d'intercepter, au moyen de JavaScript, en appuyant sur les touches flĂ©chĂ©es (en particulier, en appuyant sur les touches haut et bas), en s'assurant qu'aprĂšs avoir cliquĂ© dessus, le navigateur ne fasse pas dĂ©filer la page? Si cela est possible, quelles sont les caractĂ©ristiques de sa mise en Ćuvre dans diffĂ©rents navigateurs? Supposons qu'une page s'affiche sur une page qui ne tient pas entiĂšrement Ă l'Ă©cran. Le dĂ©placement dans les cellules de ce tableau doit ĂȘtre organisĂ© Ă l'aide des touches flĂ©chĂ©es et il est nĂ©cessaire que le navigateur ne fasse pas dĂ©filer la page lorsque vous cliquez sur ces touches.
â RĂ©pondre
Pour implémenter quelque chose comme ça, tout d'abord, vous devez désactiver la réponse systÚme standard aux actions de contrÎle. Par exemple, les touches fléchées et la molette de la souris font défiler la page, un clic droit sur une page fait apparaßtre un menu contextuel, lorsque vous cliquez sur le bouton
submit
, la fonction
form.submit()
est
form.submit()
, lorsque vous cliquez sur le champ de saisie, elle obtient le focus d'entrée, lorsque vous cliquez sur le lien, le navigateur se charge la page à laquelle il mÚne.
Cela peut se faire
de différentes maniÚres . Par exemple, comme ceci:
window.addEventListener("keydown", function(e) {
La page qui suit ne répondra normalement pas aux pressions des touches fléchées.
Une chose importante à noter ici. La méthode
preventDefault()
avant l'exĂ©cution de l'action par dĂ©faut. Par exemple, si vous cliquez sur un champ pour l'empĂȘcher d'obtenir le focus d'entrĂ©e, vous devez suspendre le gestionnaire appropriĂ© sur un Ă©vĂ©nement qui se trouve dans la chaĂźne d'Ă©vĂ©nements avant l'action par dĂ©faut. Dans notre cas, il s'agit d'un Ă©vĂ©nement de
mousedown
:
$('input').bind ('mousedown', function (event) { event.preventDefault();
Lorsque vous cliquez sur le champ de saisie, les événements suivants se produisent - dans l'ordre dans lequel ils sont affichés ici:
mousedown
focus
(avant cela, un autre objet qui perd le focus déclenchera un événement de blur
)mouseup
click
Si vous essayez d'empĂȘcher l'Ă©lĂ©ment d'obtenir le focus d'entrĂ©e, l'utilisation de gestionnaires d'Ă©vĂ©nements pour cela en commençant par le gestionnaire d'Ă©vĂ©nements
focus
ne nous aidera pas.
Question numĂ©ro 5. ArrĂȘter l'animation GIF et la touche ESC
Comment gĂ©rer le problĂšme de l'arrĂȘt de l'animation GIF lorsque vous appuyez sur la touche ESC?
â RĂ©pondre
Ici, vous pouvez utiliser la mĂȘme approche que nous avons considĂ©rĂ©e ci-dessus. Dans certains navigateurs, appuyer sur la touche ESC arrĂȘte l'animation GIF et le chargement de la page. C'est leur comportement standard, et pour les empĂȘcher de se comporter de cette façon, la mĂ©thode d'Ă©vĂ©nement
preventDefault()
nous est utile, comme précédemment. Le code de la touche ESC est 27.
Question numéro 6. ParenthÚses dans IIFE
Comment la construction à deux parenthÚses est-elle utilisée lors de la déclaration d'une expression de fonction immédiatement invoquée (IIFE)?
â RĂ©pondre
Les crochets dans cette situation permettent Ă l'analyseur de comprendre qu'il y a une fonction devant eux qui doit ĂȘtre exĂ©cutĂ©e. Mais il doit Ă©galement comprendre ce que sont ces crochets - l'opĂ©rateur de regroupement, ou une construction indiquant la nĂ©cessitĂ© d'appeler la fonction. Par exemple, si nous utilisons deux crochets comme indiquĂ© ci-dessous, nous
SyntaxError
une erreur
SyntaxError
:
function () {
Cela est dû au fait que la fonction n'a pas de nom (vous devez spécifier leurs noms dans les déclarations de fonction).
Essayons de réécrire ce code, en donnant un nom à la fonction:
function foo() {
Maintenant que la fonction a un nom, cette construction devrait thĂ©oriquement avoir l'air tout Ă fait normale du point de vue du systĂšme. Mais l'erreur ne disparaĂźt pas, bien qu'elle concerne maintenant l'opĂ©rateur de regroupement, Ă l'intĂ©rieur duquel il n'y a pas d'expression. Notez que dans ce cas, l'instruction de regroupement est suivie par l'opĂ©rateur de regroupement et non par une sĂ©quence de crochets qui indique au systĂšme que la fonction qui la prĂ©cĂšde doit ĂȘtre appelĂ©e.
IIFE est souvent conçu comme suit:
(function () {
Mais il existe d'autres façons, dont l'essence est d'indiquer d'une maniĂšre ou d'une autre Ă l'analyseur qu'avant c'est juste une expression fonctionnelle qui doit ĂȘtre exĂ©cutĂ©e:
!function () {
IIFE est largement utilisé dans la programmation JavaScript. Par exemple, cette construction est utilisée dans jQuery. Avec son aide, vous pouvez créer des fermetures. En fait, nous parlons du fait que, en utilisant IIFE, le programmeur peut exécuter du code dans la portée locale. Cela aide à protéger la portée mondiale de la pollution et permet d'optimiser l'accÚs aux variables globales. Ces conceptions sont bien réduites.
Question numéro 7. Passer le code en réponse aux demandes
Le serveur, en cours d'interaction AJAX avec le client, dans le corps de la réponse, envoie au client une chaßne d'
alert ('Boom !!!');
. Le client accepte la réponse et exécute ce code à l'aide de la fonction
eval()
. Comment ça s'appelle? AprĂšs tout, ce qui est contenu dans la rĂ©ponse du serveur n'est ni JSON, ni XML, ni HTML. Que pouvez-vous dire sur l'exĂ©cution sur le client du code qui vient du serveur sous la forme du corps de la rĂ©ponse Ă une certaine requĂȘte?
â RĂ©pondre
En fait, il n'y a pas de nom spĂ©cial pour un tel schĂ©ma d'interaction client-serveur. Et c'est un schĂ©ma d'interaction systĂšme qui est fortement dĂ©conseillĂ©. C'est aussi mauvais que de stocker du code PHP dans une base de donnĂ©es, puis de l'exĂ©cuter Ă l'aide des mĂ©thodes de langage appropriĂ©es. MĂȘme si nous ne tenons pas compte de considĂ©rations idĂ©ologiques, nous pouvons dire qu'une telle architecture est extrĂȘmement rigide, donc, si le projet oĂč elle est utilisĂ©e, il faudra, au fur et Ă mesure de son Ă©volution, changer quelque chose, ce ne sera pas facile. Nous voyons ici un exemple d'architecture systĂšme mĂ©diocre lorsque les donnĂ©es sont mĂ©langĂ©es avec du code et des Ă©lĂ©ments d'interface. Afin de changer quelque chose dans un tel systĂšme, vous devez d'abord comprendre les subtilitĂ©s de son architecture complexe, puis, aprĂšs avoir effectuĂ© les modifications, "confondre" Ă nouveau tout. Je ne parle pas de rĂ©utilisation de code.
Pour simplifier la prise en charge du code, vous devez vous efforcer d'assurer la plus grande sĂ©paration possible des parties du systĂšme et de rĂ©duire le nombre d'interdĂ©pendances de ces parties. Afin d'assurer une faible connectivitĂ© des parties du systĂšme, c'est-Ă -dire de s'assurer qu'un fragment de l'application peut en ĂȘtre extrait ou, avec la moindre complexitĂ©, remplacĂ© par un autre, vous pouvez utiliser des mĂ©canismes d'Ă©vĂ©nements ou des solutions architecturales spĂ©ciales, telles que MVC.
Question numéro 8. Effectuer des opérations lourdes dans le thread principal
Comment organiser l'exécution de certaines commandes gourmandes en ressources en JavaScript et ne pas «suspendre» l'intégralité du script?
â RĂ©pondre
JavaScript est un langage monothread. Le code des pages Web est exĂ©cutĂ© dans le mĂȘme thread et les transformations de l'arborescence DOM sont effectuĂ©es. Il y a aussi des minuteries. Chaque fois que vous effectuez des opĂ©rations consommatrices de ressources (cycles, appels Ă des fonctions "lourdes"), cela conduit Ă un ralentissement de l'interface utilisateur voire Ă son blocage complet. Si les opĂ©rations effectuĂ©es n'ont pas une charge particuliĂšrement importante sur le systĂšme, leur impact sur l'interface sera si insignifiant que les utilisateurs ne le remarqueront tout simplement pas. Afin de faire de l'informatique lourde en dehors du thread principal, le concept de web travailleurs a Ă©tĂ© introduit en JavaScript.
Si l'utilisation de travailleurs n'est pas possible, vous devez optimiser les cycles et les fonctions "lourdes". Dans le livre «JavaScript. Optimisation des performances »Nicholas Zakas dit que l'utilisateur ne remarquera rien si le flux de l'interface utilisateur est bloqué pendant 100 ms ou moins.
De cette idĂ©e, nous pouvons conclure que les calculs gourmands en ressources peuvent ĂȘtre divisĂ©s en fragments, dont la mise en Ćuvre prend un maximum de 100 ms, aprĂšs quoi le thread principal doit ĂȘtre libĂ©rĂ©.
Voici un exemple de code du livre ci-dessus:
function timedProcessArray(items, process, callback) { var todo = items.concat();
La fonction
timedProcessArray()
bloque le thread principal pendant 25 ms, exécute une séquence d'actions, puis la libÚre pendant 25 ms, aprÚs quoi ce processus est répété.
Question numĂ©ro 9. Ă propos du redimensionnement de la fenĂȘtre du navigateur
Puis-je savoir que l'utilisateur a fini de redimensionner la fenĂȘtre du navigateur?
â RĂ©pondre
Il n'y a aucun Ă©vĂ©nement spĂ©cial qui vous permet de le savoir. Mais vous pouvez savoir si l'utilisateur redimensionne la fenĂȘtre Ă l'aide de l'Ă©vĂ©nement
onresize
. Cette méthode n'est cependant pas trÚs précise.
Voici un projet de code pour résoudre ce problÚme.
var time = 0, timerId, TIME_ADMISSION = 100;
Question numĂ©ro 10. Ouverture de nouvelles fenĂȘtres et de nouveaux onglets du navigateur
Comment, à l'aide de la méthode
window.open()
, ouvrir une nouvelle fenĂȘtre de navigateur, et non un nouvel onglet?
â RĂ©pondre
Le comportement exact de la méthode
window.open()
dĂ©pend du navigateur. Opera ouvre toujours de nouveaux onglets (bien qu'ils ressemblent Ă des fenĂȘtres), Safari ouvre toujours des fenĂȘtres (bien que ce comportement puisse ĂȘtre modifiĂ©). Le comportement de Chrome, Firefox et Internet Explorer peut ĂȘtre contrĂŽlĂ©.
Donc, si un paramĂštre supplĂ©mentaire (position de la fenĂȘtre
window.open()
passé à la méthode
window.open()
, une nouvelle fenĂȘtre sera ouverte:
window.open('http://www.google.com', '_blank', 'toolbar=0,location=0,menubar=0');
Si seul un lien est transmis à cette méthode, un nouvel onglet de navigateur sera ouvert:
window.open('http://www.google.com');
Vous devez souvent ouvrir un nouvel onglet de navigateur. Il peut y avoir des problÚmes avec cela dans le navigateur Safari. Par défaut (cela dépend des paramÚtres), le navigateur, lorsque
window.open()
est appelĂ©, ouvre une nouvelle fenĂȘtre. Mais si vous cliquez sur le lien, tout en appuyant sur les touches
Ctrl + Shift/Meta + Shift
, un nouvel onglet s'ouvrira (quels que soient les paramÚtres). Dans l'exemple suivant, nous simulerons l'événement de
click
qui est déclenché lorsque les
Ctrl + Shift/Meta + Shift
sont enfoncées:
function safariOpenWindowInNewTab (href) { var event = document.createEvent ('MouseEvents'), mac = (navigator.userAgent.indexOf ('Macintosh')> = 0);
Question n ° 11. Copie en profondeur d'objets
Comment organiser efficacement la copie profonde d'objets?
â RĂ©pondre
Si l'objet dont vous souhaitez créer la copie (appelons-le
oldObject
) ne change pas, il sera plus efficace de le faire via son prototype (cela se fait trĂšs rapidement):
function object(o) { function F() {} F.prototype = o; return new F(); } var newObject = object(oldObject);
Si vous devez vraiment effectuer l'opĂ©ration de clonage d'un objet, alors le moyen le plus rapide sera rĂ©cursivement, en optimisant ce processus, parcourez ses propriĂ©tĂ©s. Il s'agit peut-ĂȘtre de l'algorithme le plus rapide pour crĂ©er des copies complĂštes d'objets:
var cloner = { _clone: function _clone(obj) { if (obj instanceof Array) { var out = []; for (var i = 0, len = obj.length; i < len; i++) { var value = obj[i]; out[i] = (value !== null && typeof value === "object") ? _clone(value) : value; } } else { var out = {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { var value = obj[key]; out[key] = (value !== null && typeof value === "object") ? _clone(value) : value; } } } return out; }, clone: function(it) { return this._clone({ it: it }).it; } }; var newObject = cloner.clone(oldObject);
Si vous utilisez jQuery, vous pouvez recourir aux constructions suivantes:
Question numéro 12. Destructeurs JavaScript
Comment créer quelque chose comme un destructeur en JavaScript? Comment gérer le cycle de vie des objets?
â RĂ©pondre
En JavaScript, un objet sera supprimé de la mémoire aprÚs la disparition de la derniÚre référence à celui-ci:
var a = {z: 'z'}; var b = a; var c = a; delete az; delete a;
L'utilisation de quelque chose comme un «destructeur» en JavaScript ne fait qu'effacer le contenu de l'objet, mais pas le supprimer de la mémoire.
Question numéro 13. Traitement des données binaires
Est-il possible de traiter des données binaires en JavaScript? Et si oui, comment?
â RĂ©pondre
Si vous devez travailler avec des données binaires dans une application JavaScript, vous pouvez essayer d'utiliser la bibliothÚque
Binary Parser . Mais son code est l'enfer. Dans ES6 +, il y a une suggestion concernant le type
StructType
(c'est la mĂȘme chose qui est reprĂ©sentĂ©e en C ++ par le type de donnĂ©es composite de
struct
). Ce type de données est nécessaire pour simplifier l'utilisation des données binaires. Travailler avec cela pourrait ressembler à ceci:
const Point2D = new StructType({ x: uint32, y: uint32 }); const Color = new StructType({ r: uint8, g: uint8, b: uint8 }); const Pixel = new StructType({ point: Point2D, color: Color }); const Triangle = new ArrayType(Pixel, 3); let t = new Triangle([{ point: { x: 0, y: 0 }, color: { r: 255, g: 255, b: 255 } }, { point: { x: 5, y: 5 }, color: { r: 128, g: 0, b: 0 } }, { point: { x: 10, y: 0 }, color: { r: 0, g: 0, b: 128 } }]);
Question numéro 14. Modification de variables dans une fonction d'une autre fonction
Comment changer des variables situées dans une fonction d'une autre fonction?
â RĂ©pondre
Ici, vous pouvez appliquer plusieurs approches:
- Vous pouvez utiliser le lien vers le contexte de la fonction qui nous intéresse (la fonction
primer()
dans l'exemple suivant) dans la fonction smth()
.
- Vous pouvez passer une fonction créée dans le contexte de la fonction
primer()
fonction smth()
.
var primer = function () { var a, b, c, d, e = {}; smth (function () { a = 1; b = 2; c = 3; d = 4; }, e); alert ([a, b, c, d, e.pewpew]); }, smth = function (callback, e) { callback (); e.pewpew = "pewpew"; }; primer ();
- Auparavant (avant Firefox 3.6), vous pouviez accéder au contexte en utilisant la propriété
__parent__
, mais déjà dans Firefox 4, cette fonctionnalité a été supprimée.
Question numéro 15. Travailler avec des fonctions
Dites-nous comment les fonctions peuvent ĂȘtre appelĂ©es en JavaScript.
â RĂ©pondre
Je suppose qu'il n'est pas nécessaire de parler de la façon d'appeler des fonctions, des méthodes et des constructeurs lors d'un travail normal avec eux. Parlons de la façon d'utiliser les méthodes
call()
et
apply()
.
Utilisation de call () pour configurer le constructeur d'un objet
Convertir des objets de type tableau en tableaux
Les objets de type tableau sont similaires aux tableaux JavaScript, mais ils ne le sont pas. En particulier, cela s'exprime dans le fait que ces objets n'ont pas de méthodes de tableaux ordinaires. Parmi ces objets, par exemple, l'objet
arguments
des fonctions traditionnelles et les résultats de la méthode
getElementsByTagName () peuvent ĂȘtre notĂ©s.
Création d'objets wrapper
Cette technique d'utilisation de
call()
et
apply()
vous permet de créer des objets wrapper. , -
foo()
,
bar()
.
:
function bar () {console.log(arguments)}
Function.call.apply()
:
function foo() { Function.call.apply(bar, arguments); }
,
Function.call.apply()
, ,
foo()
,
bar
.
â16.
, , ?
â
. , Firefox 3.6,
__parent__
, .
â17.
, , ,
eval()
?
â
, . , :
â18.
, JavaScript, , ?
â
JavaScript - « ». . . , :
$('#smth').click(function onSmthClick(event) { if (smth) {
â , . , 2 :
$('#smth'). click (function handler1 (event) { if (smth) {
â19.
JavaScript ? â , .
â
click
«» DOM. (, , ).
// jQuery $(window).bind ('click', function (e) { console.log ('Clicked on', e.target); }); // $('#pewpew').delegate ('*', 'click', function(e) { console.log('Clicked on', e.target); }); // $('#pewpew').delegate('.pewpew', 'click', function (e) { console.log ('Clicked on element with .pewpew class name'); });
â20. XHR-
XHR- jQuery?
â
, - :
function xhr(m, u, c, x) { with(new XMLHttpRequest) onreadystatechange = function (x) { readyState ^ 4 || c(x.target) }, open(m, u), send() }
- :
function xhr(m, u, c, x) { with(new(this.XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP")) onreadystatechange = function (x) { readyState ^ 4 || c(x) }, open(m, u), send() }
:
xhr('get', '//google.com/favicon.ico', function (xhr) { console.dir(xhr) });
â21. -
(reflow) (repaint) -?
â
requestAnimationFrame()
, , setInterval()
setTimeout()
. , , , , , . , JavaScript- CSS- SVG-. , , , , , , . , , .- float- ( ).
- DOM. , , , DOM ( ).
- â . ( , , ). Voici un exemple:
// element.style.left = "150px;"; // ... element.style.color = "green"; // , , element.setAttribute ('style', 'color: green; left: 150px');
- ( ).
- â (
style.display = "none"
). , .
, -, . , , , , .
- .
- DOM- ( â ).
Document.querySelectorAll()
firstElementChild
.- ,
document.getElementsByTagName()
( , DOM, ).
â22. Node.js
Node.js, , ?
â
, ( PHP Apache). , , . Node.js â . , ,
cluster . (master) - (worker). , .
â23. runInNewContext() Node.js
runInNewContext()
Node.js.
â
. , ( Node.js- Nodester). - ,
runInNewContext()
. , «», . «» , ,
runInNewContext()
.
Résumé
JavaScript . , - , .
Chers lecteurs! , - , , JavaScript , ?
