Blogs

This Blog

News

Favorite Posts

Archives

ctodx

Discussions, news and rants from the CTO of DevExpress, Julian M Bucknall

March 2011 - Posts

  • Webinar wrap-up: Julian on JavaScript IV: Good code, bad code

    After the whirlwind tour of JavaScript types, objects. arrays, and functions, it was time to take a look on how to wrap those introductory presentations into a set of good code/bad code examples. You can watch the webinar here (link coming) and download the slidedeck here, but to be honest this blog post is essentially my script for the webinar, so you might as well just read on.

    Truthy vs falsy.

    Dog Wastephoto © 2008 Sean | more info (via: Wylio)There are 6 falsy values, values that when coerced to a boolean value will evaluate as false:

    • false (type: boolean)
    • null (type: object)
    • undefined (type: undefined)
    • 0 (type: number)
    • NaN (type: number)
    • "" (type: string)

    All other values evaluate as true when coerced.

    So the condition in "if (expression)" evaluates as true only if expression is not equal to one of the six falsy values.

    Note this is great when you're trying to see if a variable, property or function exists or not:

      if (myObj.someFunction) {
        ... someFunction exists so we can call it ...
      } 
      else {
        ... someFunction is either null or undefined (or 0 or NaN, etc) ...
      }

    A longer example: the Object.create method for creating objects that inherit from some prototypal object:

      Object.create = Object.create || function (obj) {
        var F = function() {};
        F.prototype = obj;
        return new F();
      };

    Here we’re setting Object.create to itself providing that it already exists (so, in essence it’s a do-nothing operation). If it doesn’t exist, we set it to the anonymous function that is the rest of the statement. The || (or) operator used in this context means: “evaluate the first operand as a boolean, if true (truthy) return the first operand as is; otherwise return the second operand.” It’s a standard, good, succinct way of writing this kind of test.

    Here’s another example, involving a string variable. You need the color variable to have a default value if it hasn’t already been set (imagine the variable is a parameter to a function: if the caller didn’t pass anything, you want to use a default value). Don’t write this C# look-a-like:

    if ((color != null) && (color != "")) { 
      color = "black"; 
    }

    But do this instead:

    color = color || "black";

    Coercion happens when you least expect it.

    What are the results of these tests?

    console.log(0 == "") 
    console.log(false == 0) 
    console.log(0 == "0") 

    Weirdly, they all evaluate to true. That's because if the two sides of a double-equals comparison are not the same type, JavaScript coerces them to the same type and then does the comparison. Note though that this coercion means that '==' is not commutative. That is, you can't say in JavaScript : if a==b and b==c then a==c. Try it with the above set of tests: they demonstrate that 0 is “equal” to the empty string and it’s “equal” to the string “0”, yet the empty string does not equal “0”. This non-commutativity goes against everything we assume about computing and mathematics.

    Here's another, really wacky one:

    var o = { 
      toString: function() { return "42"; } 
    }; 
    
    console.log(42 == o);

    That is: this object with a toString method that returns the string “42” is “equal” to the number 42. Backing away yet?

    We should always use the triple-equals operator (even if it's obvious from the context that == will work as expected). Triple-equals works like this, in essence: if the two operands are not the same type, return false. Otherwise return the result of comparing the two operands. It works like C#'s == operator. It's known as the Identity Comparison operator.

    Use literals for booleans.

    Never ever do this:

    var isCsharp = new Boolean(false);

    Because this condition (that you’d naturally write) evaluates as true

    if (isCsharp) { 
      // Uh, whaaat? 
    }

    Always use the literals true and false.

    Use literals for objects and arrays.

    This is the best way to spot a beginner JavaScript coder:

    var color = new Object(); 
    color.R = 23; 
    color.G = 176; 
    color.B = 0; 

    Or, using an array:

    var primes = new Array(); 
    primes[0] = 2; 
    primes[1] = 3; 
    primes[2] = 5; 
    primes[3] = 7; 
    primes[4] = 11; 
    primes[5] = 13; 
    primes[‍6] = 17; 
    primes[7] = 19;

    You should declare objects and arrays by using object and array literals instead:

    var color = { 
      R: 23; 
      G: 176; 
      B: 0; 
    }; 
    
    var primes = [2, 3, 5, 7, 11, 13, 17, 19];

    Doing it this way (a) is easier to read, and (b) it's easier to include literal objects and arrays in literal objects and arrays. I’ve learned that some browsers are also optimized to create objects and arrays using the literal syntax; that is, it’s marginally slower to create them using the new keyword.

    Scope: We're not in Kansas any more.

    Scope in C# is introduced with blocks, that is, braces. Scope in JavaScript is introduced by functions.

    Quick test: What does this print?

    var f = function() { 
      var a = [2, 3, 5, 7]; 
      var foo = "outside";
      
      for (var i = 0; i < a.length; i++) { 
        var foo = a[i].toString(); 
      }
    
      console.log(foo); 
    };
    
    f();

    Reading it with your C# hat on you’d say that the console.log call prints out “outside”, since the foo variable declared in the loop body is in a different scope to the outer foo. In JavaScript, though, the two foo declarations reference the same local variable, the one in the function. Hence the logging statement prints “7”, the last value that the one and only foo variable was set to.

    How about this one? It’s essentially the same code, except that the loop body has been replaced with declaring and executing a function. In that function, a foo variable is declared.

    var f = function() { 
      var a = [2, 3, 5, 7]; 
      var foo = "outside";
    
      for (var i = 0; i < a.length; i++) { 
        var g = function(a, i) { 
          var foo = a[i].toString(); 
        }; 
        g(a, i); 
      }
    
      console.log(foo); 
    };
    
    f();

    This time, no contest: the code prints the word “outside”. If, however, you leave the var keyword out of the inner function, we get the same behavior as before. The foo variable isn’t declared in the inner function, so JavaScript checks the next outer function. There is a foo there, so it gets set when the function g() is called.

    Semicolon insertion.

    JavaScript is "forgiving" when you miss off a semicolon and will insert one where it thinks it should go. DON'T RELY ON THE INTERPRETER GETTING IT RIGHT. Also, if you forget semicolons, sometimes the error message you get back was entirely because the interpreter has invisibly added one, leading to major befuddlement.

    Silly example:

    var f = function() { 
      return 
      { 
        status: true; 
      }; 
    };
    
    console.log(f());

    seems to declare a function that returns an object with a single property called success. However, the return statement is badly formed and JavaScript will neatly add a semicolon at the end of the return keyword. If you like, this is what actually gets executed.

    var f = function() { 
      return;
      { 
        status: true; 
      }; 
    };
    
    console.log(f());

    In other words, the function returns undefined. JavaScript doesn’t even raise a warning to say that this modified interpretation includes unreachable code. You should be using JSLint (see later) to check your code.

    Parsing strings as numbers.

    parseInt converts a string to an integer. Works pretty well, but there are a couple of gotchas:

    • it stops parsing when it gets to an invalid character and returns what it's parsed so far with no error. So parseInt("42") and parseInt("42 High Street") both return 42.
    • if the first character is 0 (zero) it assumes that the number is expressed in octal. So parseInt("07") returns 7, whereas parseInt("08") returns 0 (the character “8” is invalid in octal numbers).

    Advice: always use the optional radix argument. So, parseInt("08", 10) always returns 8. If you’re prone to forgetting, write yourself a little function:

    var parseDecimalInt = function (expr) { 
      return parseInt(expr, 10); 
    };

    The '+' operator.

    ...Can mean addition of numbers or concatenation of strings. Mix your types and coercion will muddy the waters. Let’s write a quick function that prints both the type of its parameter and its value.

    var f = function(value) { 
      console.log(typeof value); 
      console.log(value); 
    };

    Now can you determine what these calls will print?

    f(41 + 1); 
    f(“a” + “bc”); 
    f(42 + ""); 
    f("42" + 1);

    Answers: number 42, string “abc”, string “42”, string “421”. When one of the operands is a string, somewhere the other operands will be coerced (there’s that word again) into strings.

    Note though that the unary plus operator is only for numbers, and is a handy way to convert a string to a (decimal) number.

    var s = "42"; 
    f(+s); 

    will return the number 42. However, note that this following code produces the number NaN (and is different in behavior than parseInt):

    s = "42 High Street"; 
    f(+s);

    The for..in statement.

    for..in enumerates an object's or an array's properties (but not methods). It superficially looks like C#'s foreach statement, but beware. The problem with it is that the properties it enumerates can bleed through from the prototype object(s).

    Let’s write a wrapper function that uses it:

    var enumerate = function (obj) { 
      console.log("enumerating..."); 
      for (name in obj) { 
        console.log(name + ":  " + obj[name]); // prints the property name followed by its value 
      } 
      console.log("...done"); 
    }; 

    Now we can use this to enumerate the properties for an empty object:

    var o = {}; 
    enumerate(o);

    The result is this:

    enumerating...
    ...done

    And now for a non-empty object:

    var o = { 
      count:42, 
      success:true 
    }; 
    enumerate(o);

    The result is this:

    enumerating...
    count: 42
    success: true
    ...done

    Now let's create an object that inherits from this object using the Object.create method declared above:

    var p = Object.create(o); 
    p.color = "white"; 
    enumerate(p);

    The result is this, and notice the for..in has enumerated the prototype’s properties as well as the single top-level property: 

    enumerating...
    color: white
    count: 42
    success: true
    ...done

    Remember that the first object is a prototype so let's augment it to show that even new properties for the prototype “bleed” through:

    o.name = "original"; 
    enumerate(p);

    Resulting in this:

    enumerating...
    color: white
    count: 42
    success: true
    name: original
    ...done

    Sometimes you only need to know the properties of that object, and not of its prototype chain. Here’s a “strict” enumeration function that uses the hasOwnProperty() method (this is inherited through the Object prototype):

    var strictEnumerate = function (obj) { 
      console.log("strict enumerating..."); 
      for (name in obj) { 
        if (obj.hasOwnProperty(name)) { 
          console.log(name + ":  " + obj[name]); 
        } 
      }
      console.log("...done"); 
    };

    With this, we can enumerate the properties that strictly belong to each object, and that are not inherited.

    strictEnumerate(o); 
    strictEnumerate(p);

    With arrays, for..in is simply not recommended (arrays are after all objects). Let’s write a property enumerator for arrays that iterates through the elements of the array using a standard for loop:

    var arrayEnumerate = function(a) { 
      console.log("enumerating array..."); 
      for (var i = 0; i < a.length; i++) { 
        console.log(i + ":  " + a[i]); 
      } 
      console.log("...done"); 
    };

    Now we can use this as well as the previous enumerate function to list the properties/elements of an array:

    var a = [2, 3, 5, 7]; 
    enumerate(a); 
    arrayEnumerate(a);
    
    a[7] = 19; // missing out [4], [5], and [‍6]
    enumerate(a); 
    arrayEnumerate(a);
    
    a.originalCount = 4; 
    enumerate(a); 
    arrayEnumerate(a);

    That last test produces this result. (Notice in particular that for..in only enumerates defined properties.)

    enumerating...
    0: 2
    1: 3
    2: 5
    3: 7
    7: 19
    originalCount: 4
    ...done
    enumerating array...
    0: 2
    1: 3
    2: 5
    3: 7
    4: undefined
    5: undefined
    6: undefined
    7: 19
    ...done

    I would recommend that you execute this code in Firebug in Forefox (or use whatever developer tools that come with your favorite browser) to see what’s going on and what gets printed.

    Don't repeat work (DREW)

    When you are writing browser-dependent code and are not using some library that abstracts out this difference, you may be repeating the same work over and over. Let's take a look at adding and removing handlers for DOM objects:

    var addHandler = function(domObject, eventType, handler) {
      if (domObject.addEventListener) {
        domObject.addEventListener(eventType, handler, false);
      }
      else { // early IE
        var ieEventType = "on" + eventType;
        domObject.attachEvent(ieEventType, handler);
      }
    };
    
    var removeHandler = function(domObject, eventType, handler) {
      if (domObject.removeEventListener) {
        domObject.removeEventListener(eventType, handler, false);
      }
      else { // early IE
        var ieEventType = "on" + eventType;
        domObject.detachEvent(ieEventType, handler);
      }
    };

    In essence: if the DOM object has a method called addEventListener (or removeEventListener), use it to add the handler, otherwise assume that we’re using an old IE and massage the parameters accordingly and use attachEvent (or detachEvent).

    Since the user can't suddenly switch browsers half way through an online session, we know with 100% certainty after the first time we execute the if statement how all subsequent ones will evaluate. We're repeating work unnecessarily. In this case, it’s not much work (a simple null/undefined condition test), but it can add up.

    One of the best ways of avoiding this is to rewrite the functions with the correct version. Remember: functions are objects. We can assign objects to variables whenever we want to. The result is a form of lazy-loading.

    var addHandler = function(domObject, eventType, handler) {
      if (domObject.addEventListener) {
        addHandler = function(domObject, eventType, handler) {
          domObject.addEventListener(eventType, handler, false);
        };
      }
      else { // early IE
        addHandler = function(domObject, eventType, handler) {
          var ieEventType = "on" + eventType;
          domObject.attachEvent(ieEventType, handler);
        };
      }
      addHandler(domObject, eventType, handler);
    };
    
    var removeHandler = function(domObject, eventType, handler) {
      if (domObject.removeEventListener) {
        removeHandler = function(domObject, eventType, handler) {
          domObject.removeEventListener(eventType, handler, false);
        };
      }
      else { // early IE
        removeHandler = function(domObject, eventType, handler) {
          var ieEventType = "on" + eventType;
          domObject.detachEvent(ieEventType, handler);
        };
      }
      removeHandler(domObject, eventType, handler);
    };

    Looking at the “add” code: the first time addHandler is called it checks for the presence of addEventListener. If it’s there, the code then replaces addHandler with the right code for the current browser, and then calls it. If it’s not there, addHandler is replaced with IE-specific code. From that moment on, every time we call addHandler we will only execute the code for the current browser. No more if statements. (Ditto for removeHandler.)

    JavaScript is a scripting language. Now forget it.

    Like all scripting languages, JavaScript allows you to construct some code as a string and then execute it from within your already executing code. There are four ways to do this: eval(), the Function constructor, setTimeout() and setInterval().

    First problem with these: the code gets evaluated twice at run-time; first when your code gets evaluated, and second when the string is evaluated as code. Another case of repeating work unnecessarily. Second problem with them is that a new instance of the interpreter has to be initialized in order to evaluate the code-as-string. With modern interpreters, there might also be extra work needed to compile/optimize the code.

    In practically every case though, the code-as-string can be rewritten as a normal function. It's rare that code has to be constructed and executed at run-time.

    Here's an example that “ticks” by printing 10 asterisks at 1/2 second intervals:

    var o = {
      count : 10,
      tick : function() {
        setTimeout("if (o.count > 0) {o.count--; console.log(\"*\"); o.tick(); }", 500);
      }
    };
    
    o.tick();

    Imagine what the interpreter has to do when it compiles that string (the first parameter of the setTimeout call). It has to parse it. It has to construct the right scope object so that the new code can access the object being referenced. It has to do this every half-second. Nasty.

    var p = {
      count : 10,
      tick : function() {
        setTimeout(function() {
          if (p.count > 0) {
            p.count--; 
            console.log("*"); 
            p.tick(); 
          }
        }, 500);
      }
    };
    
    p.tick();

    Here I’ve just rewritten the function setTimeout will call as an anonymous function. Parsed only once, and it already has access to the correct scope, etc.

    Using JSLint as a code-checker.

    One of the issues C# developers run into when they write JavaScript is that there is no compiler telling you of obvious problems with your code. Yes, they may be inadvertent errors, mistyping an identifier, missing off a semicolon, etc, but it would be nice if there was a program caught them before you had to run it and try and interpret some bizarre error that resulted. If you've followed this series from the start you'll have seen this in action every time as I made a typing error in the heat of the moment.

    Enter JSList. It's a tool written by Douglas Crockford that does exactly that. It will report on simple syntax errors in your code and its repeated use will help improve your code.

  • Sneak peek: WinForms Alert Window gains great new features (coming in v2011.1)

    We’ve implemented a couple of great new features for the WinForms AlertControl (a.k.a. – at least as far as I’m concerned – the “toaster” control) for v2011 vol.1, which will help make your apps pop.

    1) Animation effects for showing the alert window

    In previous versions the alert window used fade-in/fade-out effects to show or hide the alert window. In v2011.1, we’ve added a few more animations to show/hide the alert window: MoveVertical, MoveHorizontal, SlideVertical, SlideHorizontal. Instead of trying to describing them I’ll enjoin you to just watch them in this YouTube video.

    I start off with the current fade animation and then I show the move animations and then the slide animations (the slide ones are supposed to be smoother animations, but it’s hard to show off in a video).

    2) Ability to limit the number of simultaneously visible alert windows

    We’ve added a new property (FormMaxCount) that will help with this. Note: you can create more alert windows than FormMaxCount would seem to allow, however it’s the number of visible windows that is limited by this property. Other alert windows you create are regarded as “postponed”. Once a visible window gets hidden, one of postponed windows is promoted to be displayed in its place.

  • Advance warning: Julian on JavaScript webinar on Monday

    Just to remind you before you all slap the lids down on your laptops ready for the weekend relaxation – or the weekend gardening – I’m going to be presenting the fourth part of my Julian on JavaScript series on Monday 28 March at 10am PT. That’s next Monday at the time of writing.

    Dog Wastephoto © 2008 Sean | more info (via: Wylio)This session is going to be all about writing good JavaScript, or, if you like, writing JavaScript well, avoiding all those gotchas that can make your code buggy and crashable. In order to do that it goes without saying I’m going to have to show some really nasty JavaScript (cue evil laugh). Call these examples the doggy doo-doos on the JavaScript sidewalk and you’ll get the gist of what they’ll be like. So come prepared to pay attention or you’ll be washing a mess off your shoes.

    Of course I’ll be writing a wrap-up blog post afterwards here on ctodx.

  • DevExpress Newsletter 44: Message from the CTO

    And so, after five newsletters, we come to the final episode in my series on the SOLID principles.

    The D in SOLID - The Dependency Inversion Principle

    Let's continue our discussion of the SOLID principles. Today we'll close out this series by looking at the D in SOLID: the Dependency Inversion Principle.

    This can be expressed in two steps:

    • First, High-level modules should not depend on low-level modules; both should depend on abstractions.
    • Second, Abstractions should not depend on details; details should depend on abstractions.

    So we get the references to dependencies -- this depends on that -- but where does the inversion come from? Let's illustrate.

    Back in the first part of this series, I gave an example of my binary tree painting code. In essence, given a binary tree this code would paint a visible representation of the tree so that we could look at it and understand properties of the tree (this node is a child of this one, and so on).

    My original code failed the Single Responsibility Principle (navigation code and drawing code were intermixed) and also failed the Open-Closed Principle (the code only worked for one type of graphics context and I couldn't extend the behavior without altering the code). Let's take another look at that last one.

    In essence, the code that drew each node or edge was dependent on one particular graphics context: the normal drawing code in .NET. My high-level "paint this node" code depended on the low-level details of how painting was implemented in System.Drawing.

    I indicated at the time that the solution was to abstract out the painting into some idealized interface to a graphics context: set one up, draw a line, draw a filled circle, etc. What we're doing is inverting the dependency: instead of depending on a concrete implementation, I should be depending on an interface. Then, using the Liskov Substitution Principle, I could write an implementation of that interface that would stand in perfectly for the interface. The two modules (high level tree painting and low-level drawing a node) no longer need to know about each other: instead they "communicate" through an abstraction.

    Once we have such dependency inversion, we're on a roll. We can test classes independently of each other. We can "mock" or "fake" interfaces for the intents of testing the class in question. Classes we write don't have to depend on setting up a huge database, we can fake the abstraction.

    Or even better: we can set up factories to produce concrete behavior at run-time, driven by configuration files. We can use injection frameworks to provide data and behavior to applications that had no idea such data or behavior existed. Ninject, Spring.NET, Castle Windsor, and so on, here we come.

    Of all the principles in SOLID, I feel the Dependency Inversion Principle is possibly the most important, and also possibly the hardest to convince someone to adhere to.

    But, oh, the benefits if you do so.

    (You can watch the video here.)

    Yes, this principle is important, but like all of the SOLID principles can so easily be taken to extremes. (A really funny take-down (written using Java) can be read here.) Nevertheless, I feel the Dependency Inversion Principle (DIP) leads to much better, more readable code, than the alternative in “real-world” programs. Certainly, when I first came across it, I consciously changed the way I write code to make it apply. I didn’t necessarily use any injection frameworks as I mentioned above, but certainly, along with a switch from using an inheritance model to an interface model, I became more aware of how my code became more legible.

    Remember, the whole series is based on papers written by Uncle Bob (Robert C Martin). Click here for the PDF on DIP.

    I hope you enjoyed this series on SOLID as much as I did when writing/presenting it. Jeff and I did the whole set in one recording session (you can possibly tell: I think I look a little frazzled in this last one). Next time, we’ll talk about something else.

    Just a quick inline “advert”: Gary Short, tech evangelist for our Frameworks, has a great talk on SOLID principles and how they relate to Technical Debt. If he’s presenting this at a meeting near you, I’d recommend you go and listen in. Well worth your time.

  • Sneak peek: WinForms grid – the best keeps getting better with multi-summary footers (coming in v2011.1)

    Today is my fifth anniversary of working at DevExpress (I started on the 15th March, 2006), and just like that very first day, I’m travelling. This time, it’s chez Microsoft where we’re learning about the New Stuff coming up in the near future.

    This coming year though, more than of all those five, it seems we’ll be announcing much more functionality than ever before across all our supported platforms. Today I have a quick sneak peek for our WinForms XtraGrid control.

    The grid will be gaining multi-summary footers per column in the next major release, v2011 vol.1. As usual pictures are worth a thousand words, so I’ll show you what it all means. First here’s a grid with a simple single summary row, like what you get now.

    Grid with one summary rows

    (Click to enlarge, as with all these images.)

    Next, here’s an image showing multiple summaries in that summary row:

    Displaying multiple rows

    Finally, here’s an image showing how your end-user would add or remove summary fields from the summary row.

    Add/remove summary fields

    Stay tuned for more sneak peeks: we’re getting closer and closer to code freeze for v2011.1.

  • Webinar wrap-up: Julian on JavaScript III

    On Monday, I presented my third webinar in my series on learning JavaScript when you’re a C# developer. The topic: functions. You can watch the webinar here. You can download the slidedeck here. Here’s the unedited JavaScript file containing all the examples.

    Southern Guilford (NC) High School Street Signagephoto © 2010 Joe Wolf | more info (via: Wylio)First off, I talked about how you define a function. My recommendation is the function literal way:

    var cl = function(obj) {
      console.log(obj);
    };
    
    var f = function fib(n) {
      if (n === 0) return 0;
      if (n === 1) return 1;
      return fib(n-1) + fib(n-2);
    };

    The reason for this is twofold. First, once you start writing JavaScript in earnest, you’ll be writing anonymous function literals all over the place as callbacks, etc. So it’s best to continue that tradition when you declare a function you’ll be calling in code. Second, it reinforces the idea that functions are objects in JavaScript, they’re not statically bound to an object. The first example there is known as an anonymous function literal (the function has no name before it’s assigned to a variable), and the second example is a named function literal, and is great for writing recursive functions. Why? Just imagine this bit of code:

    var g = f;
    f = undefined;
    cl(g(6));

    I’m assigning the function object in f to a new variable g. I then set f to undefined (so if the function was calling itself through f, it would crash), and then I print out the result of g(6).

    Next on the webinar I talked about the various invocation patterns for calling a function. First up was method invocation. This is the simplest idea to grasp for C# developers: you’ve got some object and you call a method on that object. The this variable inside the function is set to the object you’re calling the method on, just as in a C# instance method. Here’s my printer object example that prints out the number of times it gets called when it prints some other object:

    var printer = {
      callCount : 0,
      log : function(obj) {
        console.log("--- count:" + this.callCount++);
        console.log(obj);
        console.log("---");
      }
    };
    
    var someObj = {a:42};
    
    printer.log(someObj); // prints 0 as count
    printer.log(someObj); // prints 1 as count

    Notice something that I didn’t really point out in the webinar: the log method MUST use the this variable to get at the callCount property, otherwise the normal scoping rules for JavaScript come into play (which we discussed later on).

    I then showed a little fun bit of code you can’t do in C#: extending the someObj object to have a callCount property and copying over the log function from my printer object. Lo and behold it works.

    someObj.callCount = 23;
    someObj.log = printer.log;
    someObj.log(someObj);// prints 23 as count

    The next way of calling a function is using function invocation. Easy in concept – just call the function but not via an object – but the one that causes the most problems. The reason is that the this variable gets set to the Global Object.

    var cl2 = function(obj) {
      var isGlobalObject = function(obj) {
        return obj === window;
      };
      
      console.log("Is this the Global Object? " + isGlobalObject(this).toString());
      console.log(obj);
    };

    I had a brief sidebar on the Global Object, noting that it has no name, but that the browser will add a property called window to it that references it. In other environments, this property may be called something else. The Global Object is where all unowned variables and functions end up, as global public properties. Anyway this code shows that the this variable for the cl2 function is set to window.

    The third way of calling a function is through constructor invocation. Several gotchas to watch out for here. First of all you must call the function through the new keyword.

    var Person = function(lastName, firstName) {
      this.firstName = firstName;
      this.lastName = lastName;
    };
    
    Person.prototype.print = function() {
      var name = this.lastName + ", " + this.firstName;
      cl(name);
    };
    
    var me = new Person("Bucknall", "Julian");
    me.print();

    Second, the new keyword will create a brand new object, and set its constructor to the function and then call it. The this variable will be set to this new object. The final unusual thing about constructors is that the default return value is the new object; you don’t have to return it explicitly.

    The big problem about constructor functions is that you sometimes forget to use the new keyword. Constructors are normal functions, there’s nothing in the language that marks them as special.

    me = Person("Oops", "Crash");
    me.print();

    As I showed in the webinar, what happens here is that this in Person refers to the Global Object, and so the function corrupts it by adding a couple of new properties. Since the function has no return statement, undefined is returned instead and stored in me. The next statement throws an error. I showed how to get round this by using this type of code:

    var Person = function(lastName, firstName) {
      if (!(this instanceof Person)) {
        return new Person(lastName, firstName);
      }
      
      this.firstName = firstName;
      this.lastName = lastName;
    };

    So, if the this parameter is not an instance of Person assume that the caller forgot the new and construct a new object properly and return it. If not, just proceed as normal for a constructor.

    The final way to call a function is to use the function’s apply or call methods: the “apply” invocation. Yes, a function is an object, so it can have properties and methods. Both apply and call work by calling the function on an explicit object that you supply. Arguments to the function are either passed one-by-one (call) or as an array (apply).

    someObj = { callCount : 23 };
    otherObj = { foo : 42 };
    
    printer.log.call(someObj, otherObj);
    printer.log.apply(someObj, [otherObj]);

    So here I declare some object with a property of callCount and another just to log. I then call the printer.log method but force someObj to be the caller object and pass in otherObj as  the object to log, first using call then using apply.

    I then talked about scope in JavaScript and stated that it’s by function and not by block. This is perhaps the hardest difference between C# and JavaScript to overcome. Scope is by function. To resolve a variable or a reference JavaScript will look in the current function, and if not found will look in the next most containing function. If not there, move onto the next outer function. And so on, so forth. Eventually it will look in the Global Object. this always just refers to the function itself; it doesn’t go “deeper”.

    My example was a rudimentary ticker object, It outputs an asterisk, and then one second later, another.

    var ticker = {
      char : "*",
      show : function() {
        cl(this.char);
        setTimeout(function() { cl(this.char); }, 1000);
      }
    };
    
    ticker.show();

    The first asterisk is output, but the one that should have been output a second later comes out as undefined. The reason is that the this in the timeout’s callback function is the Global Object, not ticker at all. What I did to overcome this problem was to add a local variable in the show method.

    var ticker = {
      char : "*",
      show : function() {
        var self = this;
        cl(self.char);
        setTimeout(function() { cl(self.char); }, 1000);
      }
    };

    The self variable captures the value of this, and now the anonymous timeout function works correctly. Since the function has no local variable called self, the interpreter looks in the next enclosing function, which happens to be show. Bingo, there it is, and the property access now works. I went a little further and modifies ticker to continue outputting asterisks at one second intervals, until its stop property was set to false:

    var ticker = {
      char : "*",
      stop : false,
      show : function() {
        var self = this;
        
        var callback = function() {
          cl(self.char);
          if (!self.stop) {
            setTimeout(callback, 1000);
          }
        };
    
        callback();
      }
    };
    
    ticker.show();

    Since the binding of this to the Global Object is such a pain in the callback function, I showed how you could write a special bind function that did it for you:

    var bind = function(obj, func) {
      return function() {
        return func.apply(obj);
      };
    };

    This function takes an object and a function that, when called, needs the passed-in object as the this variable. bind returns a function that does the binding by using the “apply” invocation. Here’s the version of ticker that uses this bind function.

    var ticker = {
      char : "*",
      stop : false,
      show : function() {
        var callback = bind(this, function() {
          cl(this.char);
          if (!this.stop) {
            setTimeout(callback, 1000);
          }
        });
    
        callback();
      }
    };

    Finally I talked about closures, especially since my examples of function scope used them.

    Here’s the simple example of creating a counter object from a function that forms a closure around the startValue parameter:

    var createCounter = function(startValue) {
      return function() {
        return startValue++;
      };
    };
    
    var counter = createCounter(0);
    cl(counter()); // 0
    cl(counter()); // 1
    cl(counter()); // 2

    The createCounter function returns a function that, when called, will return the current value of startValue and increment it. The startValue variable however is only defined in the createCounter function and that function terminates early on. The variable continues to exist though in the closure created by the call and the returned function making a reference to it.

    I then showed a nice example of how to create private variables in an object through the use of closures. This is an incredibly important pattern to learn: it’s used all over in libraries like jQuery,

    var createCircle = function(x, y, radius) {
      return {
        getX : function() {
          return x;
        },
        getY : function() {
          return y;
        },
        getRadius : function() {
          return radius;
        }
      };
    }
    
    var circle = createCircle(1, 3, 10);
    
    cl(circle.getX());
    cl(circle.getY());
    cl(circle.getRadius());

    The createCircle function creates a new object that defines a circle on the screen. It has a position (described by the X and Y coordinates) and a radius. Notice though that the returned object does not have any properties: it just defines three “getters” that return these values. The values are stored in the closure formed by calling the original function. The x, y, and radius values act as if they were “private properties” of the object in C# terms, although of course there is no such thing in JavaScript.

    All well and good, but what if you wanted to extend that object with another private property only accessible through a getter and setter? You do it through another closure of course. Here’s a way to add a modifiable color property through its own get/set methods:

    var addColorProperty = function(obj, color) {
      obj.getColor = function() {
        return color;
      };
      obj.setColor = function(newColor) {
        color = newColor;
      };
    };
    
    addColorProperty(circle, "red");
    cl(circle.getColor()); // red
    circle.setColor("blue");
    cl(circle.getColor()); // blue

    You call the addColorProperty passing in the object you want to extend and the default color value. It adds a getter and a setter to the object for you, and the closure makes the color variable the private field that is accessed by those methods.

  • Sneak peek: Date interval grouping in server mode. Again the WinForms grid scores (coming in v2011.1)

    In version 11.1, we'll be adding support for group intervals for date-time columns in XtraGrid, our WinForms grid. In server mode, no less, in order to minimize the data transferred across the wire. You’ll be able to change group intervals via a single property setting in server mode in the exactly the same way as you do in regular binding mode.

    The following animated image shows the user changing a column's group interval in XtraGrid:

    XtraGrid_ServerMode_GroupInterval

    (Click to make larger.) I do like the “Smart” grouping interval, I must say.

    There’s more new WinForms sneak peeks coming. Stay tuned.

  • Sneak peek: Incremental search in column filter dropdowns? WinForms grid, of course (coming in v2011.1)

    Another great feature coming in the next major version of XtraGrid: the ability to use incremental search in column filter dropdowns.

    One way to filter a column is to use column filter dropdowns. These dropdowns can be represented as regular or checked lists. In either case, incremental search is now supported to give your end-user the ability to quickly locate filter values.

    In this case a picture is truly worth a thousand words:

    XtraGrid_FilterIncrementalSearch

    (Click to make larger.)

    There’s more new WinForms sneak peeks coming. Stay tuned.

  • Sneak peek: WinForms grid gets better unbound columns in server mode (coming in v2011.1)

    In the next major version of DXperience, v2011.1, XtraGrid is going to be gaining some more intelligence in Server mode. From that version onwards, unbound grid columns can be populated with data using expressions. In server mode. With the expression being evaluated on the server, not on the client.

    The expression you write (or your end-user writes) can reference other columns and use many different functions and operators. Here’s an example of the Expression Editor being invoked at run-time on an unbound column in an instance of an XtraGrid running in server mode.

    ServerMode_UnboundExpressionEditor

    (Click for a larger version.)

    There’s more new WinForms sneak peeks coming. Stay tuned.

  • WinForms and DXperience v2011

    [UPDATE 7-Mar-2011: fixed grammar, spelling, links]

    There has been some feedback recently that we’re not paying enough attention to WinForms in our product plans and roadmap, or, putting it another way, we’re paying way too much attention to WPF, Silverlight, ASP.NET MVC, this, that, and the other to the detriment of WinForms. Let’s be specific here and repeat what I said in the 2011 Roadmap with regard to WinForms:

    With regard to the Windows Forms controls, it is most likely that there will be a large number of smaller enhancements and new features rather than any large complex new control. The reason for this is simple: we believe that our offerings for this platform are very mature and robust. That’s not to say that our premier controls like the grid are in any shape or form “complete”, but we recognize that more benefits will come from performance improvements, usability improvements, and simplification of the APIs than by adding major features. Nevertheless, we welcome any thoughts and feedback you may have regarding features and functionality for our WinForms controls.

    The scheduler will be enhanced with the year view. It is likely that this will be in the later release rather than the earlier one.

    The rich text edit control will be improved with the same features described in the Silverlight section.

    sand sculptorphoto © 2005 Ambra Galassi | more info (via: Wylio)When I presented my webinars about the ideas we had for our roadmap at the time of our annual Summit (first, second) in December, I also specifically asked for your thoughts about our WinForms controls. In particular, those WinForms controls that were not part of reporting, charting, pivot grid, scheduler, rich text edit, since they are all cross-platform efforts that share functionality across the platforms. What should we be looking at, what could we implement, what would benefit most from new functionality. I had a grand total of 11 replies. There were all very good (and I thank everyone who emailed me), and I circulated them among our “thick client” R&D team.

    Since then, possibly some three months before the actual release, I posted the very first sneak peek about DXperience v2011.1. Coincidentally, it was about some new functionality in WinForms: the Ribbon is gaining a mini toolbar (or whatever the official fluent UI name for it is). I have a couple more ready to write about here, again about enhancements to XtraGrid (one’s about expressions in unbound columns in server mode, one’s about date group intervals in server mode, the other’s about incremental search in column filter dropdowns). Today I got another email from R&D about a new just-added WinForms feature for XtraGrid that we can’t talk about just yet for competitive reasons. It’ll be in XtraGrid first, and then we’ll move it over to the other grids later.

    So, I will reject outright that we’ve somehow “abandoned” WinForms and are ignoring it and our customers there. We had some great new features in 2010, and we’ll have some more in 2011.

    The other argument is that we’re paying too much attention to all of the other platforms, Oh, and WPF’s performance sucks. And, while we’re at it, it’s dying or dead, didn’t you hear? And, of course, anyone who writes thick client apps uses WinForms. (Most of those comments make me laugh, they’re similar to what we heard from our Delphi customers when we started developing for WinForms in the first place in 2002.)

    Look, like it or not, we’re in a very competitive business. All software is. Perceptions about DevExpress come from many sources, some of which we can control, some not. We want to make sure that those perceptions are as positive as we can. Examples are “How open in DevExpress?”, “How well do they support us in the community?”, “How quickly and well do they respond to support queries?”, “How attuned are they to my particular market segment?”, etc. Another one is, do people perceive that we are at the forefront of (or willing to support) new technologies?

    This particular perception is a double-edged sword in a way. Yes, customers want us to support new technologies – after all, when they’re ready to move forward with those new technologies themselves, they want their favorite vendor to already be established. And, no, they don’t want us to do so because it will inevitably mean that resources are going to be diverted from their favorite product onto the new stuff.

    Me, I view it as planting an apple orchard. Once the orchard is established, all that’s required is pruning, weeding, chopping down the dead trees, yadda yadda. This frees us up to try and create other types of produce: kiwi fruit anyone? Maybe those other orchards will succeed, maybe they won’t. Maybe kiwis will go out of fashion before we get established. Maybe we can’t make any money at it. But, I would stand firm and say we have to, nay, are obligated to, move the company as a whole forward by trying.

Next page »
LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, Silverlight, ASP.NET, WinForms, HTML5 or Windows 8, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2014 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners