JavaScript for C# Developers - p-patel/software-engineer-knowledge-base GitHub Wiki

https://app.pluralsight.com/library/courses/js4cs/table-of-contents

JavaScript Basics

  • C# dynamic keyword
  • Closures - C# lambda closures,
  • arrays (really more of a collection, than just an array in JavaScript) - push(), pop(), shift(), unshift(), indexOf(), lastIndexOf(), slice(), splice(), concat()
  • JavaScript function is like Func<> in C#, build up objects with function properties to create 'classes'

JavaScript Functions

  • parameter lists are a 'suggestion' in JavaScript - any parameters not passed are set to undefined, there is no function overloading. You can also pass more parameters to a function than is specified in the function definition
  • arguments object is available in a function as an array
  • all functions return a value. if a function returns no value explicitly, it returns defined
  • a function is an Object that has properties and member functions - e.g. length property or call toString()
  • define anonymous function (no function name is specified)
  • this keyword: applies to the owner of the function. bind() lets you change the owner
  • closures - work in the same way as in C#
  • scope - different than C# (in C# scope is defined by brackets, in JavaScript brackets do not define a scope - the only thing that defines a scope in JavaScript is a function
  • namespaces (the global pollution problem) - define anonymous self-executing functions to define scope and protect the global namespace:
(function() {
  var count = 0;
  var max = 10;

  function printSomething(){
    alert("print something");
  }
})();

(the anonymous function is wrapped in brackets and then executed immediately with a further set of brackets)

Also define namespaces as follows:

var WilderMinds = WilderMinds || {};
WilderMinds.Models = WilderMinds.Models || {};

Using these two concepts together:

(function(ns) {
  var currentDate = new Date();

  ns.currentTime = function(){
    return currentDate;
  };
})(window.WilderMinds = window.WilderMinds || { });

//function has been added to the WilderMinds namespace which is defined in the global scope
  • Summary: functions are central to JavaScript; big differences between C# and JavaScript functions; closures, scoping, 'this' and namespaces can tame JavaScript

Object-oriented JavaScript

Dynamic Objects

  • create dynamic objects using { }
  • access object properties using dot or bracket syntax
  • dynamic objects - malleability, works in a similar way to C# dynamic types

Classes

  • no such things as a class in JavaScript, but they can be mimicked
  • functions that are being treated as class declarations use Pascal casing naming:
function Customer(name, company){
  this.name = name;
  this.company = company;
}

var cust = new Customer("Shawn", "Wilder Minds");
var name = cust.name;

new keyword in JavaScript is used to find a function with the name specified after the keyword new and returns an object with the shape defined in the function

  • member functions can be added in the same way too
  • encapsulation - public members uses this. within the function definition, non-public members (e.g. private) uses var with closures created to make them accessible from other functions
  • properties (should be only used when you have a specific use, most of the time they are created as public fields):
function Customer(name){
  var _name = name;

  Object.defineProperty(this, "name", {
    get: function () {return _name;}
    set: function (value) { _name = value; }
  });
}
  • static members:
function Customer(name, company) {
  this.name = name;
  this.company = company
}

Customer.mailServer = "google.com";

var cust = new Customer();
var svr = c.mailServer;  //Nope!
var svr = Customer.mailServer;  //mailServer is defined as part of the Customer function definition, not the instance (i.e. it is static)

static functions can be defined in the same way that rely on this static data

  • The Prototype Object: JavaScript is a prototype language. Every object created has a prototype object that is associated with it. Objects added to the prototype object will be available to every instance of that type.

  • Sharing a function - that way each instance doesn't have it's own copy of the function!

function Customer(name, company){
  this.name = name;
  this.company = company;
}

//Gives access to each instance of Customer
Customer.protoype.mailServer = "mail.google.com"
Customer.prototype.send = function(msg) {
  var svr = this.mailServer;
};

var cust = new Customer("Shawn", "My Company");
cust.send("Hey buddy");

property on the prototype is shared between instances, property in the constructor means it is instance data

  • Prototype inheritance: Inheritance is related to the prototype object. You have chained prototype objects to create a basic is-a relationship
function Animal(foodType){
  this.foodType = foodType;
}

Animal.prototype.feed = function(){
  alert("Fed the animal:" + this.foodType);
}

var a = new Animal("None");
a.feed();  // None
var test = a instanceof Animal; // true

function Cow(color) {
  this.color = color;
}

Cow.prototype = new Animal("Hay");

var c = new Cow("White");
c.feed();  // Hay
var test = c instanceof Animal;  // true
var test2 = c instanceof Cow;  //true

can fake abstract classes (not commonly used and has caveats!):

var Animal {
  foodType: "None",
  feed: function() {
    log("Fed the animal: " + this.foodType);
  }
};

var a = new Animal(); // fails (not a constructor)

function Cow(color){
  this.color = color;
  this.foodType = "Hay";
};

// inheritance magic
Cow.prototype = Animal;

var c = new Cow("White");
c.feed();  // Hay
var test = c instanceof Animal; // error!
var test2 = c instanceof Cow; // true

there is probably a better way in JavaScript to accomplish what you require than using fake abstract classes

  • private members - via closures and local variables

  • protected members - not supported

  • overloaded constructors - no, but no overloaded functions so same

  • Interfaces

  • interfaces aren't necessary, get comfortable with Duck Typing (if it looks like a duck, sounds like a duck and walks like a duck it is a duck). In JavaScript you can pass an object that adheres to the contract between two objects but not having to have that contract resolve around the type

function sendEmail(r){
  var to = r.email;
  var name = r.name;
  }

var Owner = {
  to: "[email protected]";
  name: "Shawn";
  }

sendEmail(Owner); // works!

function Customer(name, email){
  this.name = name;
  this.to = email;
  this.balance = 0;
  }

c = new Customer("Bob", "[email protected]");
sendEmail(c); // also works!
  • Object reflection: When working with objects and classes, you may need to interrogate the members of classes
var cust = {
  name: "Shawn",
  "company name": "Wilder Minds",
  sendEmail: function() { ... }
};

for (var prop in cust){
  alert(prop);  // property name
  alert(cust[prop]); // property value
}

detecting properties:

var c = new Customer();

var has = c.hasOwnProperty("name");
var isEnum = c.propertyIsEnumerable("name");
  • Extension Methods:
  • add helper functions onto existing well-known types
  • simply use object's prototype
Array.prototype.calculateCount = function() {
  return this.length;
};

var a = ["one", "two"];
var count = a.calculateCount();
  • Object Patterns: many patterns exist for Object Creation

  • prototype pattern (seen above)

  • module pattern

  • revealing prototype pattern

  • revealing module pattern

  • etc.

  • refer to Dan Wahlin's great 'Structuring JavaScript" pluralsight course for more information...

  • Summary

  • OOP is possible in JavaScript and most frameworks use and own code will be built in the same way

  • You can leverage C# skills to work out what the best way in JavaScript is (though the way things are done in C# do not map exactly to JavaScript)

  • Objects and "Classes" represent the basic data structures in JavaScript

  • Your OOP skills can be used in JavaScript

  • "Classes" aren't real, but they can model real-world relationships

  • Not all features of C# classes are supported (e.g. protected members and interfaces), but many features aren't necessary

Practical Application

  • Strict mode (what's disallowed)

  • use of variables not first defined with var

  • duplicate object properties

  • writing to read-only properties

  • modifying arguments Object

  • Require.js - http://requirejs.org

  • Uses the Asynchronous Module Definition (AMD) pattern

  • Dependency injection for JavaScript

  • loads scripts as they are needed instead of all at the start

  • "Compiling" JavaScript

  • Compilation in C# verifies code is syntactically correct and creates IL code packages

  • In JavaScript use JSLint to check for correctness and use minification for packaging

  • Summary

  • Need to learn ecosystem as well as the JavaScript language