
Mon cheminement plus ou moins sérieux en programmation a commencé avec l'écriture de programmes en C #, parfois j'essayais d'écrire en JavaScript, et de temps en temps je tombais dans la stupeur dans des situations où j'indiquais incorrectement le nom de la variable et le découvrais plus tard plusieurs années une heure de débogage, car je n'étais pas près de mon compilateur, ce qui m'aiderait dans les moments difficiles. Après un certain temps, en plus de C #, j'ai commencé à écrire beaucoup de code JavaScript et maintenant je peux le faire sans trop de difficulté, je ne suis plus confus par le cast de type implicite et le typage dynamique.
Dans cet article, je voudrais systématiser mes connaissances de base de ces langues et considérer leurs similitudes et leurs différences. Cet article peut servir de guide aux développeurs C # qui souhaitent apprendre JavaScript et vice versa. Je tiens également à noter que cet article décrit les capacités de JS côté client, car je n'ai aucune expérience de développement sur Node.js. Donc, si vous n'avez toujours pas perdu votre intérêt, commençons.
Espace de noms et modules js
Dans chaque programme, afin d'éviter les conflits dans les noms des variables, fonctions, classes ou autres objets, nous les combinons dans certaines zones. Ainsi, si deux zones différentes contiennent des éléments du même nom, aucun conflit ne se produit.
En C #, les espaces de noms sont utilisés pour diviser un programme en parties. L' namespace
mots clés namespace
utilisé pour les déclarer. Par exemple, si nous voulons créer un ensemble de composants d'interface utilisateur, il est logique de les mettre tous dans un même espace de noms, par exemple, Components
. Il est habituel que l'espace de noms ait le nom suivant [AssemblyName].[DirectoryName].[DirectoryName].[...]
. Dans chaque fichier, la classe du composant d'interface utilisateur doit être placée à l'intérieur de l'espace de noms:
Le contenu du fichier ComboBox.cs
:
namespace AssemblyName.Components { public class ComboBox {
Pour commencer à utiliser des composants, vous devez les importer de l'espace de noms comme suit à l' using AssemblyName.Components
. Avec cette méthode de connexion en ligne, nous importons tous les objets dans le fichier actuel.
JS utilise des modules ES dans le même but. Lorsque vous les utilisez, nous émulons dans une certaine mesure le comportement des espaces de noms en écrivant du code supplémentaire. Prenons le même exemple avec une bibliothèque de composants. Disons que nous avons le dossier Components
, qui contient les composants de l'interface utilisateur ComboBox.js
, Button.js
, Button.js
, etc. Afin d'obtenir un comportement similaire par rapport à l'espace de noms dans le dossier Components
, vous devez créer un fichier index.js
qui contiendra le code suivant:
export { default as Dialog } from './ComboBox'; export { default as Button } from './Button'; export { default as Checkbox } from './Checkbox';
Pour utiliser ces composants, vous devez les importer dans le fichier actuel. Cela peut être fait comme suit: import * as Components from './../Components'
, après le mot clé from, nous devons spécifier le chemin d'accès au dossier dans lequel se trouvent tous les composants décrits.
Façons de déclarer des variables
Le mot-clé var
Comme vous le savez, C # est un langage de programmation fortement typé, par conséquent, lors de la déclaration d'une variable, le compilateur doit connaître son type, pour cela il est généralement indiqué avant son nom.
double pi = 3.14; User user = new User(); int[] a = new[] { 0, 1, 2 };
Mais nous pouvons également dire au compilateur qu'il doit déduire le type de lui-même à partir de l'expression suivant le signe d'affectation. Cela a été rendu possible en introduisant le mot clé var
dans C # 3.0.
Avec var
nous pouvons créer des objets de type anonyme:
En JavaScript, vous pouvez également utiliser le mot clé var
pour déclarer des variables, cependant, contrairement à C #, la portée de ces variables sera la fonction entière ou l'objet window
si la variable a été déclarée en dehors de la fonction.
var a = 5 // - window function go() { var a = 6 // - go // ... }
Bien que vous ayez la possibilité de déclarer des variables à l'aide de var
en JavaScript, ce n'est pas recommandé maintenant, après la publication de la norme ES6, le mot clé let
été ajouté, ce qui vous permet également de déclarer des variables, mais son avantage est que leur portée sera le bloc dans lequel ils sont déclarés, pas la fonction entière.
Constantes
C # et JavaScript utilisent le mot-clé const
pour déclarer un champ constant. Certes, il convient de noter que le concept de constante dans ce cas est différent pour ces langues.
En C #, une constante est une expression qui peut être entièrement évaluée au stade de la compilation, c'est-à-dire les constantes peuvent être des nombres, des booléens, des chaînes ou des références nulles.
const int c1 = 5; const int c2 = c1 + 100; const string c3 = ""; const bool c4 = true; const User human = null; const User human = new User(firstName);
En JavaScript, la valeur d'une constante ne peut pas non plus être modifiée, cependant, il n'y a aucune restriction sur la valeur comme en C #, vous pouvez lui assigner des valeurs / objets / tableaux. Cependant, si un objet est affecté à une constante, alors la constante elle-même est protégée contre les modifications, mais pas les propriétés à l'intérieur:
const c1 = 5; const c2 = c1 + 100; const c3 = ""; const c4 = true; const user = { name: "" }; user.name = "";
Mot-clé void
En écrivant cet article, j'ai expérimenté des fonctions dans la console et par habitude j'ai commencé à décrire la fonction comme dans C # void SomeFunction...
et ce fut une grande surprise pour moi quand j'ai découvert que le mot-clé JavaScript est void
. Il s'est avéré que void
en JavaScript est un opérateur unaire qui calcule la valeur d'un opérande, puis le rejette et renvoie undefined
.
alert("!"); // "!" alert(void "!"); // undefined
Ainsi, nous pouvons dire que l'utilisation de void
indique clairement l'absence de valeur de retour; pour plus de détails sur les exemples de son utilisation, voir l' article suivant.
En C #, void
pas un opérateur, mais a essentiellement une signification similaire. Ici, cela indique l'absence d'une valeur de retour de fonction:
public void SampleMethod() {
Cependant, comme vous pouvez le voir dans l'exemple ci-dessus, void
à l'endroit où le type de la valeur de retour est généralement indiqué, et ce n'est pas un hasard, car en C # void
également un type.
var t = typeof(void); t.Name
void
tant que type ne peut être utilisé que dans un contexte dangereux lorsque vous travaillez avec des pointeurs.
unsafe { void* identifier;
Mot-clé new
En JavaScript, le new
mot clé est un opérateur et est utilisé de la manière habituelle pour de nombreux langages de type C pour créer un objet.
function Animal() { //... } const animal = new Animal();
En C #, new
peut être utilisé aux fins suivantes:
- pour créer des objets;
- pour masquer le membre hérité de la classe de base;
- pour limiter les types pouvant être utilisés comme arguments à un paramètre de type dans une classe générique.
Le premier cas est similaire à l'utilisation de new
en JavaScript.
class Animal {
Types de données de base
Chaque langue a des types de données - des primitives sur la base desquelles d'autres types de données sont construits, regardons les types de données qui nous sont fournis en C # et JavaScript.
Types C # primitifs:
- Entier
sbyte
: sbyte
, short
, int
, long
- Entier non signé:
byte
, ushort
, uint
, ulong
- Caractères Unicode:
char
- Jeu de caractères Unicode:
char
- Numéros à virgule flottante:
float
, double
- Precimal Decimal:
decimal
- Valeur booléenne:
bool
La classe de base est Object
.
Pour JS:
Types de données primitifs:
- Numéro
number
- Chaîne de
string
- Booléen
boolean
null
spécial- Signification spéciale
undefined
symbol
Le type de base est Object
.
Après avoir étudié les primitives des deux langues, nous pouvons arriver aux conclusions suivantes:
- Au lieu d'un ensemble suffisamment large de types de nombres, JavaScript a un seul
number
type; - JavaScript n'a pas de type
char
; à la place, utilisez un type string
; - Dans les deux langues, le type de base est
Object
; - Une caractéristique distinctive de JS est que
null
et undefined
sont séparés en types distincts, tandis qu'en C # null
est un mot-clé indiquant l'absence de valeur. - JS a le type de
symbol
, qui est utilisé principalement à l'intérieur du standard JavaScript lui-même, afin de pouvoir ajouter de nouvelles fonctionnalités sans conflit avec la base de code existante.
En règle générale, il existe de plus en plus d'applications dans lesquelles il est nécessaire de traiter des données sur le client, ce qui nécessite une plus grande précision dans les calculs. JavaScript n'a actuellement pas la capacité intégrée de travailler avec de grands nombres, mais dans un avenir proche, il est prévu d'ajouter un nouveau type de BigInt
. Pour résoudre des problèmes similaires en C #, il existe une classe System.Numerics.BigInteger
.
Vérification du type d'objet
La vérification de type est une opération assez typique pour la plupart des langages de programmation. Selon le type, nous pouvons effectuer différentes actions. Par exemple, considérons un exemple de vie: vous entendez une sonnette, si un voisin ivre est venu vers vous (un objet avec le type de voisin ivre ) pour emprunter de l'argent, il est peu probable que vous lui ouvriez la porte, mais si votre meilleur ami est derrière la porte (un objet avec le meilleur type ami ), alors n'hésitez pas à le laisser entrer dans l'appartement. C # et JavaScript fournissent également des fonctionnalités pour vérifier le type d'objets.
typeof
opérateur
Pour les informations de type, C # et JavaScript ont tous deux l'opérateur typeof
. Voyons comment cela fonctionne dans les deux langues:
En C #, l'opérateur typeof
est appliqué à un type et renvoie un objet de la classe Type
qui contient toutes les informations de type.
namespace Zoo { public class Animal {} } Type t = typeof(Animal); t.Name
Dans JS, typeof
renvoie une chaîne indiquant le type d'opérande.
typeof 30 // 'number' typeof Symbol() // 'symbol' typeof undefined // 'undefined' // typeof new Animal() // object typeof null // 'object' typeof [1,2,3] // 'object' // typeof function() {} // 'function'; typeof class C {} // 'function';
Dans l'exemple ci-dessus, vous pouvez remarquer certaines fonctionnalités de cet opérateur. Il semble logique que l'expression typeof new Animal()
renvoie la chaîne 'Animal'
, et typeof [1,2,3]
- la chaîne Array
, cependant paradoxalement, le résultat dans les deux cas est 'object'
. De plus, du fait que les classes dans JS sont un wrapper sur les fonctions, l'expression typeof class C {}
renverra 'function'
au lieu de 'class'
. Un autre fait intéressant est que le typeof null
expression typeof null
renverra 'object'
. En JavaScript, cet opérateur a un gros inconvénient: tous les objets non primitifs se ressemblent, ils ont tous le même type d' object
.
Il est à noter qu'en JavaScript, typeof
peut s'appliquer à tout: objets, fonctions, classes, etc ... En C #, cet opérateur ne s'applique qu'aux types.
En plus d'obtenir des informations sur un type, il peut parfois être utile de vérifier qu'un objet appartient à un type particulier.
En C #, il existe un opérateur is
à ces fins.
class Person { }
En JavaScript, pour savoir à quel type appartient un objet, vous devez utiliser l'opérateur - instanceof
.
function Person() {} function Programmer() {} // Programmer Person Programmer.prototype = Object.create(Person.prototype); var person = new Person(); var programmer = new Programmer(); console.log(person instanceof Person); // true console.log(person instanceof Programmer); // false console.log(programmer instanceof Person); // true console.log(programmer instanceof Programmer); // true
Vérification booléenne et nulle
Presque partout, afin de ne pas obtenir d' Null reference exception
, avant d'utiliser une variable, nous la vérifions pour null
, et dans le cas de JavaScript, également pour undefined
.
En C #, nous voyons constamment un code similaire:
if(user != null && String.IsNullOrEmpty(user.name)) { user.SetName(""); }
En JavaScript, cette construction peut être écrite un peu plus courte. Cela est dû au fait que, contrairement à C #, en JavaScript, beaucoup de valeurs, sauf false
lors de la conversion, sont également considérées comme false
:
null
undefined
- "" (Ligne vide)
0
NaN
(pas un nombre)
Ainsi, le code C # ci-dessus peut être écrit comme suit:
if (user && !user.name) { user.setName(""); }
ou
user && !user.name && user.setName("");
En raison du fait que null
vérifications null
sont omniprésentes, l' opérateur de propagation nulle a été ajouté en C # 6.0 .?
.
Code C #:
if (user != null && user.parent != null && user.parent.parent != null) { user.parent.parent.SetName(""); }
Avec son aide, cette section de code peut être réécrite comme suit:
user?.parent?.parent?.SetName("");
En JavaScript, généralement comme suit:
user && user.parent && user.parent.parent && user.parent.parent.setName("");
Définition des valeurs par défaut
Une autre opération courante consiste à définir des valeurs par défaut, à partir de la version 2.0 dans C # Null Coalescing Operator est apparu - ??
.
Les deux lignes de code C # suivantes sont équivalentes:
var name = user != null && user.name != null ? user.name : ""; var name = user?.name ?? "";
En JavaScript, une opération similaire est généralement effectuée comme suit.
var name = user && user.name || "";
Cependant, nous pouvons utiliser les opérateurs &&
et ||
uniquement si 0
, false
et la chaîne vide ne sont pas des valeurs valides.
Dans un avenir prévisible, opérateurs ?.
, ??
devrait apparaître en JavaScript (ils ont maintenant franchi l'étape Stage0 ), plus de détails sur ces opérateurs en JavaScript peuvent être trouvés dans l' article .
Ce mot-clé
C # et JavaScript ont this
. Habituellement, en C #, la compréhension de l'objectif est simple, mais en JavaScript, c'est l'un des concepts de langage les plus compliqués. De plus, nous considérerons l'application de this
sur des exemples.
En C #, le this
pointe vers l'instance actuelle de la classe.
class User { public string Name { get; set; } public void PrintEmployee() { Console.WriteLine(this.name); } } var employee = new Employee(); E1.PrintEmployee();
Dans cet exemple, dans l'expression Console.WriteLine(this.name)
, this
pointe vers la variable employee
.
Comme this
s'agit de l'instance actuelle de la classe, elle ne peut pas être utilisée dans des méthodes non liées à un type spécifique, par exemple, dans des méthodes statiques.
En JavaScript, this
s'appelle le contexte de l'appel et sera déterminé lors de l'appel de la fonction. Si vous exécutez la même fonction dans le contexte de différents objets, elle recevra un différent this
:
var user = { firstName: "" }; var admin = { firstName: "" }; function func() { alert( this.firstName ); } user.f = func; admin.g = func; // this : user.f();
De plus, en JavaScript, il est possible de spécifier explicitement la valeur de this
fonction en utilisant: call
, bind
, apply
. Par exemple, l'exemple ci-dessus peut être réécrit comme suit:
var user = { firstName: "" }; var admin = { firstName: "" }; function func() { alert( this.firstName ); } // this : func.call(user); // func.call(admin); // func.bind(user)();// func.bind(admin)();//
Restructuration
Il est souvent nécessaire d'affecter plusieurs champs d'un objet à des variables locales. Par exemple, à quelle fréquence observez-vous un code similaire?
void Method(User user) { var firstName = user.FirstName; var lastName = user.LastName;
À ces fins, vous pouvez utiliser la déstructuration. Les deux langues prennent en charge cette fonctionnalité à des degrés divers.
C # 7.0 a introduit un nouveau type de fonction appelé déconstructeur pour prendre en charge la déstructuration. Afin de déclarer un déconstructeur, nous devons définir une méthode appelée Deconstruct
, dont tous les paramètres doivent être déclarés avec le modificateur out
:
class Person { public string FirstName { get; set; } public string LastName { get; set; }
La prise en charge de la déstructuration ou (affectation de la déstructuration) en JavaScript est apparue dans la sixième norme EcmaScript. Avec son aide. Vous pouvez affecter un tableau ou un objet à plusieurs variables à la fois, en le divisant en parties.
let [firstName, lastName] = ["", ""]; let [firstName, _ ] = ["", ""]; let { firstName, lastName } = { firstName: "", lastName: "" }; let { firstName } = { firstName: "", lastName: "" };
Il est à noter que la restructuration en JavaScript a plus de fonctionnalités qu'en C #:
- Changez l'ordre des variables;
- Pas besoin de déclarer explicitement les déconstructeurs;
- Prise en charge de la déstructuration des baies;
- Définition des valeurs par défaut;
- Assigner les propriétés d'un objet à une variable avec un nom différent;
- Prise en charge de la déstructuration imbriquée.
Conclusion
Dans cet article, nous avons discuté uniquement des concepts les plus élémentaires des langages C # et JavaScript. Mais de nombreux aspects sont restés inchangés:
- collections
- les fonctions
- cours
- multithreading
Chacun de ces sujets est assez étendu et sera divulgué plus loin dans un article séparé.