Comparison of C # and JavaScript. The basics

C # and JavaScript


My more or less serious way of programming began with writing programs in C #, sometimes I tried writing in JavaScript, and every now and then I fell into a stupor in such situations when I incorrectly indicated the name of a variable and found out about it later many many years debugging hour, since there was no my compiler next to me, who would help me out in a difficult moment. After a while, besides C #, I started writing a lot of JavaScript code and now I can do it without much difficulty, I am no longer confused by the implicit type conversion and dynamic typing.


In this article I would like to systematize my basic knowledge of these languages ​​and consider their similarities and differences. This article can serve as a guide for C # developers who want to learn JavaScript and vice versa. I also want to note that this article describes the capabilities of client JS, since I have no development experience on Node.js. So, if you still have not lost interest - let's start.


Namespace and js modules


In each program, in order to avoid conflicts in the names of variables, functions, classes or other objects, we combine them into certain areas. Thus, if two different areas contain elements with the same name, no conflict will occur.


C # uses namespaces to split a program into parts. To declare them, use the namespace keyword. For example, if we want to create a set of user interface components, then it is logical to put them all in one namespace, for example, Components . Thus it is accepted that the namespace has the following naming [AssemblyName].[DirectoryName].[DirectoryName].[...] . In each file, the user interface component class must be placed inside the namespace:


Contents of the ComboBox.cs file:


 namespace AssemblyName.Components { public class ComboBox { // ... } } 

To start using components, you need to import them from the namespace as follows using AssemblyName.Components . With this connection method in one line, we import all objects into the current file.


In JS, ES modules are used for the same purpose. When using them, we to some extent emulate the behavior of namespaces by writing additional code. Consider the same example with the component library. Suppose we have a Components folder that contains the components of the user interface ComboBox.js , Button.js , Button.js and so on. In order to get similar behavior compared to the namespace in the Components folder, you need to create an index.js file, which will contain the following code:


 export { default as Dialog } from './ComboBox'; export { default as Button } from './Button'; export { default as Checkbox } from './Checkbox'; // ... 

In order to use these components, you must import them into the current file. This can be done as follows: import * as Components from './../Components' , after the keyword from we need to specify the path to the folder in which all the described components are located.


Variable declaration methods


var keyword


As you know, C # is a strongly typed programming language, so when declaring a variable to the compiler, its type must be known; for this, it is usually indicated before its name.


 double pi = 3.14; User user = new User(); int[] a = new[] { 0, 1, 2 }; 

But we can also tell the compiler that it must deduce the type itself from the expression after the assignment sign. This is made possible by the introduction of the keyword var in version C # 3.0.


 // i - int var i = 5; // a - int[] var a = new[] { 0, 1, 2 }; 

With var we can create objects of anonymous type:


 // anon -      var anon = new { Name = "Terry", Age = 34 }; var type = anon.GetType();//"<>f__AnonymousType0`2" 

In JavaScript, you can also use the var keyword to declare variables, however, unlike C #, the scope of these variables will be the entire function or the window object if the variable was declared outside the function.


 var a = 5 //   - window function go() { var a = 6 //   -  go // ... } 

Although you have the ability to declare variables using var in JavaScript, but now it is not recommended to do this, after the release of the ES6 standard, the let keyword was added, which also allows you to declare variables, but its advantage is that their scope will be the block in which they are declared, not the whole function.


Constants


In both C # and JavaScript, the keyword const used to declare a constant field. True, it is worth noting that the concept of a constant in this case is different for these languages.


In C #, a constant is an expression that can be fully computed at compile time, i.e. constants can be numbers, logical values, strings or null references ..


 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); //,   

In JavaScript, the value of a constant can also not be changed, but there are no restrictions imposed on the value as in C #, it can be assigned any values ​​/ objects / arrays. However, if an object is assigned to a constant, then the constant itself is protected against the change, but not the properties inside it:


 const c1 = 5; const c2 = c1 + 100; const c3 = ""; const c4 = true; const user = { name: "" }; user.name = ""; //  user = 5; // ,   

void keyword


While writing this article, I experimented with functions on the console and, as a result, I started describing a function as in C # void SomeFunction... , and for me it was a big surprise when I found out that there is a void keyword in JavaScript. As it turned out, void in JavaScript is a unary operator that calculates the value of the operand, then discards it and returns undefined .


 alert("!"); // "!" alert(void "!"); // undefined 

Thus, we can say that the use of void clearly indicates the absence of a return value, for more details on examples of its use, you can find in the next article .


In C #, void not an operator, but in fact it has a similar meaning. Here it indicates the absence of the return value of the function:


 public void SampleMethod() { // ... } 

However, as can be seen in the example above, void in the place where the type of the return value is usually indicated, and this is not accidental, because in C # void also a type.


 var t = typeof(void); t.Name // System.Void 

void as a type can only be used in an unsafe context when working with pointers.


  unsafe { void* identifier; //,    } 

Keyword new


In JavaScript, the new keyword is an operator, and is used in a way that is familiar to many C-like languages ​​— to create an object.


 function Animal() { //... } const animal = new Animal(); 

In C #, new can be used for the following purposes:



The first case is similar to the use of new in JavaScript.


 class Animal { //... } var animal = new Animal(); 

Basic data types


In each language there are data types - primitives, on the basis of which other data types are built, let's consider the data types provided to us in C # and JavaScript.


C # primitive types:



The base class is Object .


For JS:


Primitive data types:



The base type is Object .


After studying the primitives of both languages, you can come to the following conclusions:



As a rule, now there are more and more applications in which it is necessary to perform data processing on the client, which requires greater accuracy in calculations. Currently, there is no built-in ability to work with large numbers in JavaScript, however in the near future we plan to add a new type of BigInt . To solve similar problems in C # there is a class System.Numerics.BigInteger .


Object Type Check


Type checking is a typical operation enough for most programming languages. Based on the type, we can perform various actions. For example, consider an example from life: you hear a doorbell, if a drunken neighbor came to you (an object with the Drunken Neighbor type) to borrow money, then you are unlikely to open the door for him, but if the door is your best friend (an object with the best friend ), then you do not hesitate to let him into the apartment. C # and JavaScript also provide tools for checking the type of objects.


typeof operator


For type information, both C # and JavaScript have a typeof operator. Let's look at how it works in both languages:


In C #, the typeof operator is applied to a type and returns an object of class Type , which contains all the information about the type.


 namespace Zoo { public class Animal {} } Type t = typeof(Animal); t.Name // 'Animal' t.FullName // 'Zoo.Animall' t.GetMethods //    t.GetFields //     // ... 

In JS, typeof returns a string indicating the type of the operand.


 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'; 

In the example above, you can notice some features of this operator. It seems logical if the expression typeof new Animal() would return the string 'Animal' , a typeof [1,2,3] - the string Array , but no matter how paradoxical it is, the result in both cases is 'object' . Also, due to the fact that classes in JS are a wrapper over functions, the expression typeof class C {} returns 'function' instead of 'class' . Another interesting fact is that the typeof null expression returns an 'object' . In JavaScript, this operator has a big drawback: all non-primitive objects for it are the same person, they all have the same type object .


It is worth noting that in JavaScript typeof you can apply to anything: objects, functions, classes, etc ... In C #, this operator applies only to types.


is and instanceof


In addition to obtaining information about the type, it is sometimes useful to check that the object belongs to a particular type.


In C # for these purposes there is an operator is .


 class Person { } // Programmer  Person class Programmer : Person { } var person = new Person(); var programmer = new Programmer(); person is Person //true person is Programmer //false programmer is Person //true programmer is Programmer //true 

In JavaScript, in order to find out what type the object belongs to, it is necessary to use the - instanceof operator.


 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 

Boolean and null check


Almost everywhere, in order not to get a Null reference exception , before using a variable, we check it for null , and in the case of JavaScript, also for undefined .


In C #, we constantly see similar code:


 if(user != null && String.IsNullOrEmpty(user.name)) { user.SetName(""); } 

In JavaScript, this construct can be written slightly shorter. This is due to the fact that, unlike C #, in JavaScript, a set of values ​​other than false when casting is also regarded as false :


  1. null
  2. undefined
  3. "" (empty line)
  4. 0
  5. NaN (not a number)

Thus, the above C # code can be written as follows:


 if (user && !user.name) { user.setName(""); } 

or


 user && !user.name && user.setName(""); 

Due to the fact that checks for null occur everywhere, Null Propagation Operator was added to C # 6.0 .? .


C # code:


 if (user != null && user.parent != null && user.parent.parent != null) { user.parent.parent.SetName(""); } 

With it, this code section can be rewritten as follows:


 user?.parent?.parent?.SetName(""); 

JavaScript usually does this:


 user && user.parent && user.parent.parent && user.parent.parent.setName(""); 

Setting Default Values


Another common operation is setting default values, from version 2.0 in C # the Null Coalescing Operator appeared - ?? .


The following two lines of C # code are equivalent:


 var name = user != null && user.name != null ? user.name : ""; var name = user?.name ?? ""; 

In JavaScript, this operation is usually done as follows.


 var name = user && user.name || ""; 

However, we can use the operators && and || only if 0 , false and the empty string are not valid values.


In the foreseeable future, operators ?. ?? should appear in JavaScript (they have now passed the Stage0 stage), for more information on these operators in JavaScript, see the article .


Keyword this


Both C # and JavaScript have the keyword this . Usually, in C #, understanding this purpose is easy, but in JavaScript it is one of the most complex language concepts. Next, consider the use of this in the examples.


In C #, the keyword this points to the current instance of the class.


 class User { public string Name { get; set; } public void PrintEmployee() { Console.WriteLine(this.name); } } var employee = new Employee(); E1.PrintEmployee(); 

In this example, in the Console.WriteLine(this.name) expression Console.WriteLine(this.name) , this points to the employee variable.


Since this is the current instance of the class, it cannot be used in methods not bound to a specific type, for example, in static methods.


In JavaScript, the value of this is called the context of the call and will be determined at the time of the function call. If the same function is run in the context of different objects, it will receive a different this :


 var user = { firstName: "" }; var admin = { firstName: "" }; function func() { alert( this.firstName ); } user.f = func; admin.g = func; // this    : user.f(); //  admin.g(); //  func();// undefined -    this -   window 

In addition, JavaScript has the ability to explicitly specify the value of this using functions: call , bind , apply . For example, the above example can be rewritten as follows:


 var user = { firstName: "" }; var admin = { firstName: "" }; function func() { alert( this.firstName ); } // this    : func.call(user); //  func.call(admin); //  func.bind(user)();//  func.bind(admin)();//  

Destructuring


It is often necessary to assign several object fields to local variables. For example, how often do you see such a code?


 void Method(User user) { var firstName = user.FirstName; var lastName = user.LastName; //... } 

For such purposes, you can use destructuring. This feature is supported to varying degrees by both languages.


In C # 7.0, a new kind of function called deconstructors appeared to support destructuring. In order to declare a deconstructor, we need to define a method called Deconstruct , all of whose parameters must be declared with an out modifier:


 class Person { public string FirstName { get; set; } public string LastName { get; set; } //   public void Deconstruct(out string firstName, out string lastName) { firstName = this.FirstName; lastName = this.LastName; } } ... Person person = new Person { FirstName = "", LastName = "" }; (string firstName, string lastName) = person; (string firstName, _ ) = person; 

Support for destructuring or (destructuring assignment) in JavaScript appeared in the sixth standard EcmaScript. With her help. You can assign an array or an object to several variables at once, breaking it apart.


 let [firstName, lastName] = ["", ""]; let [firstName, _ ] = ["", ""]; let { firstName, lastName } = { firstName: "", lastName: "" }; let { firstName } = { firstName: "", lastName: "" }; 

It should be noted that JavaScript restructuring has more features than in C #:



Conclusion


In this article, we discussed only the most basic concepts of C # and JavaScript. But many aspects remained unaffected:



Each of these topics is quite extensive and will be disclosed further in a separate article.

Source: https://habr.com/ru/post/414593/


All Articles