Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Dec 1, 2020

Array(n) constructor

JavaScript Array constructor can be used in the follow syntax.

  const items1 = new Array(2); //(2) [empty × 2]
  //or 
  const items2 = Array(2); //(2) [empty × 2]

So you may think that, you can iterate the array using for/loop or method such as map, forEach with the newly created array. But it doesn't work.

for(let i = 0; i < items1.length; i++) {
   console.log(i);
}

// or 

const newItems = items1.map((value, index) => {
   return index;
});

Why? What this constructor or function does, is essenetially the following. It does not have anything inside, even though the length is set to 2.

  const items = [];
  items.length = 2;

If what you want is to initialize an array of a number of undefine value or any other value, you can do the following.

const items1 = Array(2).fill(); //(2) [undefined, undefined]
//or
const items2 = [...Array(2)];  //(2) [undefined, undefined]
//
const items3 = Array(2).fill().map((_, index) => index); //[0, 1]
//
const items4 = Array.from({length: 2}, (_, index) => index)); //[0, 1]

Apr 12, 2016

A JavaScript interview question which can be fixed by 'let'

A very popular JavaScript interview question on Lexical scope and closure is like the follow.

for (var i = 1; i < 6; i += 1) {
    //(function (i) {
 setTimeout(function() {
          console.log("I've waited " + i + " seconds!");
     }, 1000 * i);
    //})(i);
}

The code has a bug, that all the log output is the same, like the following.

Previously, to solve that is to uncommon the lines in previous code, because we can close the variable "i" in lexical scope using function. So that you can have something like

Now we have ES2016 or ES6, the new solution is actually very simple, just change "var" to "let". This is because let support block scope. In the loop block, the variable "let i" is private to the block. Every loop an new private scope is created. If you use transpiler such as typescript or babel, you can make it works in browser like IE10 or below and Safari 9. The transpilers are actually pretty smart, the following is transpiled by typescript, pretty impressive.

Jul 8, 2015

Class in ES6, Typescript, Angular2 and Angular1

ES6 class

Class was proposed in ECMAScript 4, which was abandoned, and ES5 does not have Class. Now ES6 is finalized and it has class.

So what is the big deal of it? Should I use it? Will it change the nature of JavaScript? Here is an excerpt from ECMAScript 2015 specification

Although ECMAScript objects are not inherently class-based, it is often convenient to define class-like abstractions based upon a common pattern of constructor functions, prototype objects, and methods. The ECMAScript built-in objects themselves follow such a class-like pattern. Beginning with ECMAScript 2015, the ECMAScript language includes syntactic class definitions that permit programmers to concisely define objects that conform to the same class-like abstraction pattern used by the built-in objects.

It turns out, ES6 class is essentially a constructor function (which should be called with "new" keyword), it still uses prototype inheritance Here is some test case which is used in ES6 compatibility table, which also confirms this.

 class C {}
 return typeof C === "function";

return typeof class C {} === "function";

return typeof class {} === "function";

The question of "Should I use ES6 class or closure function?" is essentially "Should I use constructor/prototype or closure function". If you google constructor/prototype vs closure function, you can find lots of discussion about this, such as Efficiently creating JavaScript objects: closures versus prototypes, Some Javascript constructor patterns, and when to use them and of course Douglas Crockford's Private Members in JavaScript.

Developers of classical language tend to love ES6 class, maybe because class is the familiar way to create object. It is true that ES6 class(prototype) use less memory when you create thousands of instance of one class with shared methods (which can be factored out prototype object), but most of the time, I just need to create one instance adhocly. Also JavaScript runtime like V8 will create hidden class anyway when it finds that two objects has the same shape, and also memory is really cheap nowadays, so memory efficiency is not really important here.

Another advantage of ES6 class is that it simplify inheritance, if you really need to use inheritance as reusability vehicle like EmberJs or BackboneJs, this is really a good reason to use ES6 class. But the bigger problem is that inheritance is really bad idea.

Closure is confusing to classical language developer, but Douglas Crockford claim it is the best idea in the history of programming language. To me, closure is more flexible, readable, powerful and it supports encapsulation and does not require to use the "this" variable. I really like Douglas Crockford's class-free object-oriented programming.

Class in TypeScript and Angular 2.0

Angular team is now building Angular2 with Typescript. In Angular2, we can write application using ES6 class with typescript . If you follow the quick start guide of Angular2, you will find some code like the following.

/// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap} from 'angular2/angular2';

@Component({
    selector: 'my-app'
})
@View({
    template: '<h1>My first Angular 2 App</h1>'
})
class AppComponent {

}
bootstrap(AppComponent);

In Angular1, we use closure to create service, controller, directive. In angular2, angular team seems to use class extensively. Why? In the Keynote on AtScript at ng-europe 2014, Misko (the creator of Angular) described the problem in angular1 is that angular1 API is too complicated to use. They want to have a better abstraction and simpler API. Angular team decided to use lots ES6 features such as class, module. But these features are not enought. So they want to extend the language by creating AtScript. The following is relationship between AtScript, TypeScript, ES6, and ES5. The feature they really want are "Annotation" and "Introspection", these features allow you declaratively add functionality to your class.

Later, Angular team communicate to typescript team their needs in typescript. Since typescript 1.5 start to support class with decorator ( which is essentially the annotation in AtScript), Angular team cancel AtScript and use typescript to write Angular2.

How can class with decorator simplify the Angular2 api? In the above code, the class is annotated with decorator, which is pretty neat. This code is transpiled to the following javascript (ES5)

var __decorate = //omit some implementation

var angular2_1 = require('angular2/angular2');
var AppComponent = (function () {
    function AppComponent() {
    }
    AppComponent = __decorate([
        angular2_1.Component({
            selector: 'my-app'
        }),
        angular2_1.View({
            template: '<h1>My first Angular 2 App</h1>'
        })
    ], AppComponent);
    return AppComponent;
})();
angular2_1.bootstrap(AppComponent);

We can see that the decorator can modify the class definition declaratively. So class with decorator in typescript is good. Actually decorator is already proposed in ES2016, so we may see decorator get standardized very soon.

Class in Angular1

So how about class in Angular1 ? Can we use class to simplify our code or improve performance in Angular1? After "Angular 2: Built on TypeScript" announced, people are thinking of future-proof way to write code with angular1. Obviously Angular2 is using class, a lot, should we use class now in Angular1. From the very beginning, we use closure to create Angular1 component, now some Angular1 projects switch to use class exclusively to replace closure. Suddenly, it seems that closure is obsolete in Angular1, is it?

First, angular1's architecture has not changed and will keep the same in the future, the change will be in Angular2. Angular1 is still using closure internally to create service, directive, controller. If you use class in Angular1, it will not simplify our code, it may even add some complexities to your code. Secondly, angular1 does not use class or class with decorator internally, there is no advantage in that sense.

In the following, I will implement a service, a controller and a directive using class and closure and compare them side by side. And the code is written in typescript, because it support ES6 class and optional type. The source code above can be found https://github.com/fredyang/class-or-closure-angular1, the demo page can be found here.

First let's see take a look on service. If we want to use class to define service in angular1, we should use module.service method, because I want to use the class directly. If we use closure, we should use module.factory.

// common interface of Backend service
// implementing it seems to be good idea, it is used by
//both ClassBackend and closureBackend
interface IBackend {
    login(userName: string, password: string) : ng.IPromise
}

///-------service implemented by class---
class ClassBackend implements IBackend {
    //save $q for reference
    constructor(private $q) {
    }
    login(userName: string, password: string) {
        //access $q via 'this' reference
        return this.$q.when(password === '123');
    }
}

//use module.service method, as it will use 'new' to call class ClassBackend
// which it is essentially a constructor function
angular.module('app').service('classBackend', ClassBackend);


///------service implemented by closure----
angular.module('app').factory('closureBackend', function ($q): IBackend {

    return {
        login: function(userName: string, password: string) {
            //access $q via closure
            return $q.when(password === '123')
        }
    };

});

Now let's implement controller. Here, we can use class to define controller directly, because angular1 treat controller as constructor.

///common interface of controller
//implementing IUser is optional, seems the expression
//in html view is not strong typed yet.
interface IUser {
    isAuthenticated: boolean;
    userName: string;
    password: string;
    login(): ng.IPromise
}

///------controller implemented by class-----------
class ClassController implements IUser{
    constructor(private classBackend:IBackend) {
    }

    isAuthenticated = false;
    userName = 'Fred Yang';
    password = '123';

    login() {
        return this.classBackend.login(this.userName, this.password)
            .then((isAuthenticated) => {
                //need to arrow function to access 'this'
                this.isAuthenticated = isAuthenticated;
                return isAuthenticated;
            });
    }
}

angular.module('app').controller('ClassController', ClassController);

/////---------controller implemented by closure--------------
angular.module('app').controller('ClosureController',
    function (closureBackend:IBackend) : IUser {

    //here I want to avoid to use "this.xxx = yyy"
    // and explicitly return an object instead implicitly return this
    // so that I can use closure
    var rtn = {
        isAuthenticated: false,
        userName: 'Fred Yang',
        password: '123',
        login: function () {
            return closureBackend.login(this.userName, this.password)
                .then(function (isAuthenticated) {
                    //access isAuthenticated via closure variable,
                    //without using arrow function
                    rtn.isAuthenticated = isAuthenticated;
                    return isAuthenticated
                });
        }
    };

    return rtn;
});

Now let's implement directive. I can not use the class directly to define directive here, I still use closure function, inside which I new an instance of the class.

///------------ directive "implemented" by class --------
//implementing ng.IDirective is optional
class CounterWidget implements ng.IDirective {

    constructor(private $timeout) {
        //all the dependencies have to be attached to
        // instance "this"
        //
        // "private" just make the compiler think it is 'private'
        // but it still accessible externally in the generated
        //javascript
    }

    restrict = "EAC";

    template = "<div>counter-widget-class:{{count}}</div>";

    scope = {
        delay: "="
    };

    link = (scope, $elem, attrs) => {
        //access dependencies via "this"
        var $timeout = this.$timeout;
        //
        var delay = scope.delay || 1000;
        scope.count = 1;
        (function repeat() {
            $timeout(function () {
                scope.count++;
                repeat();
            }, delay);
        })();
    }
}


angular.module('app').directive("counterWidgetClass", function ($timeout) {
    //directive is still created using closure under the hood
    return new CounterWidget($timeout);
});


//---- directive implemented by closure ---------
//implementing ng.IDirective is optional
angular.module('app').directive('counterWidgetClosure',
    function ($timeout):ng.IDirective {
        //$timeout is closured and it is accessible to inner function
        return {
            restrict: "EAC",

            template: "<div>counter-widget-closure:{{count}}</div>",

            scope: {
                delay: "="
            },

            link: (scope:any, $elem, attrs) => {
                //
                var delay = scope.delay || 1000;
                scope.count = 1;
                (function repeat() {
                    $timeout(function () {
                        scope.count++;
                        repeat();
                    }, delay);
                })();
            }
        };
    });

From the above samples, I find that

  • The implementation in class is more complicated, verbose, rigid, it does not really encapsulate private data, but the syntax may be more friendly to java or c# developer.
  • The implementation in class is more simple, terse, flexible, and it can encapsulate private data, but it feels wired to classical developer.

Because angular2 use lots class, it does not mean that you have to use class exclusively in Angular1. Using class will not put you better place in migrating to Angular2, because Angular2 is whole new architecture. Whatever you write today in Angular1, you need to rewrite in Angular2. Until I write code in Angular2, I should still keep writing components using closure function in angular1.

Thanks for taking the time to read this. Feedback, critiques and suggestions are welcomed.

Apr 24, 2012

"use strict" and "this" in ES5

"this" is a special variable in JavaScript. If a Constructor function is called without "new", the "this" variable inside the constructor will reference the Global object. We can use "use strict" in ES5 to prevent this happening.

(function () {
  "use strict";
  console.log(this === window); //false
 })();

You can also use the "use strict" in global, but this will affect all module

 "use strict";
 console.log(this === window); //true
 (function () {
  console.log(this === window); //false
 })();

Dec 7, 2011

What does the size of a JavaScript Library say about it?

When people introduce a JavaScript library, they often mention that the size of the library is very small, like "it is small and light weight, xx K minified, in fact is about yy k when gzipped". Does this means a library runs fast or use less memory? Neither. We know that 1k size virus can use up all your machine resource, and make it dead slow, right? What it means the library can be transported to client side faster. Normally the more features a library provide, the bigger the size. You can use profiler (like the one built in Chrome) to collect data when using the library in real life scenario.

Sep 22, 2011

The design principle of viaProxy

[update: the library is now in github, and the sample code discussed in this post is here]

viaProxy is a client side JavaScript library that can be used to build complex, fast and fluid web UI yet in a manageable code complexity. It is a set of low-level api which is built on top of jQuery and enable you to synchronize your view and model using imperative programming (code only) or declarative programming ( mark-up only) or both. You can use it to write testable views, modules, plugins, and aggregate them into complex view.

About a year ago, that is after I wrote jquery-matirx, I had been thinking a problem in a project. We were developing a rich web UI using JavaScript intensively , but as the logic of application grows, the JavaScript code explode, and become buggy and spaghetti like, as our logic is distributed every where in the handler. Although, I create a solution to dynamically load view into the page at client side with some template, but does not solve the issue completely. So I think, is there a UI framework to address this issue systemically. I studied libraries like Backbone.js and knockoutjs , which seems to be good UI framework. Initially, I thought I had sufficient JavaScript competency to use them, it turned out I had lots of difficulties to write a "hello world" app with them, and even greater difficulties in solving a real world scenario. The syntax and convention are just too cryptic for me, and it is hard for me to do unit test and debug. So I decided to write my own, that is how I started viaProxy

Before I discuss how to use the library, I want to put the design principle of the library upfront, which is fundamentally important to use the library.

The principle is to separate model interaction from model presentation.

You can think of model interaction as CRUD(CREATE, READ, UPDATE, READ), and model presentation as view rendering. A view is the typically the UI that user can see and feel, a model is typically business object of your application. I want to use the word "typically", because sometimes, the difference between view and model can be blurred. A view can be just another model, we will discuss this in the future post.

Let's take a look at "Hello world" application to understand how model and view play together. The application allows user enter a name, and click a button, the application display a greeting message. Here is markup that defined the view.

<label>Please input your name: <input type="text" id="txtName"/>
 <input id="btnGet" value="Get message" type="button"/>
</label>

<div id="divMessage"/>

And here is a piece of javascript to implement the user story.

$(function () {                                       
                                                      
 $("#btnGet").click(function () {     
                
  var name = $("#txtName").val();                     
  if (name) {                                         
   $("#divMessage").text("Hello," + name);            
  } else {                                            
   $("#divMessage").text("");                         
  }
                                                   
 });                                                  
});

You might be laughing at how stupid the code it is. But there is nothing wrong with it, in fact, it is simple and elegant, if this is everything that the user want from the app. However what user want is far more complex web application. If you have a little bit web UI programming experience, you probably agree that, by applying this style of implementation to develop complex UI, the code will soon explode and become spaghetti.

Let's take a closer look. In the click handler, it by-pass the model and directly update the view, in fact it does not even define a model, it just directly convert user's click action into updating view. When user stories grows, we need to create more viewsto implement them, and we need more view handlers to take care of user interaction. Our view handler will have hundreds or thousands lines code doing thing like "If user input this, do this, if input that do that, because of this change, we also update an this view, because that change, we also need to update that." Very soon, the code complexity will grow out of control. So what is wrong? The fundamental fault is mixing model interaction with model presentation, because our view handler has too much thing to worry.

Let's refactor the above code using viaProxy. At first sight, the refactory may require you to write more code, what I show is how viaProxy works under the hood, I will introduce higher level viaProxy API which can reduce your code to minimum or no code at all. The first step is to define a model, which is missing from the previous implementation. Without model, we can not possibly separate a model interaction from model presentation. Model is center of an app. So here is the model.

var rootProxy = via();            
var helloAppModel = {                                     
   name: null,                                                        
   greeting: "Hello",                                                 
   message: function() {                                              
     return this.name ? this.greeting + "," + this.name : "";          
   }
};                                                                 
rootProxy.insert( "helloApp",  helloAppModel);

The model is a javascript object which has 3 members name, greeting, and message. The message function combines greeting and message. It is very pure and simple, that it does not inherit from anything other than object, it does not use hard-to-understand concepts like "Observerable", "viewModel", which are used in other framework. As your can see, we put our model into a repository using a proxy with a namespace "helloApp", this prevents you from direct access to the model, all access must be via the proxy, this is why the library is named viaProxy.

Now let's take on model interaction. Instead of using raw DOM event directly, we wrap it into higher abstraction, view event. View event can be one-to-one mapped to DOM event, but it can be customized event. For example, we can create an "enter" event which will trigger when "keypress and keycode === 13" event triggers, I will cover that later. Here is how we attach a view handler to the view event, like below.

$( "#btnGet" ).addViewHandler( "click", "helloApp.name", 
  function( viewContext ) {
    var value = $( "#txtName" ).val();  
    viewContext.updateModel( value );
    //or 
    //via("helloApp.message").update(value);
} );

The view handler is also associated with a path("helloApp.name") which is pointer to the model in repository. In the view handler, it does only one thing, updating the model with the user's input, however it does not care about updating the divMessage, because this is the job of model handler. This is a big difference from the previous implementation. Remember, model handler is only place do model presentation. Here is the model handler to update the divMessage.

$( "#divMessage" ).addModelHandler( "helloApp.message", "afterUpdate", 
   function ( modelContext ) {
     var value = modelContext.currentValue();
     //or 
     //var value = via("helloApp.message").get();
     //"this" refer the divMessage
     $( this ).text( value);
} );

The semantics here is when model event "afterUpdate" happens to "helloApp.message" in the repository, call this handler to update view "divMessage". In the model handler, it also does only one thing, update the view. You maybe notice that the previous view handler update "name" property, why the event of "afterUpdate" is raised for "message" property, this is because viaProxy knows this dependencies between "name" and "message". Here you don't need to write some thing like "observerable()" which is used by other library. After creating the model, adding a viewHandler, a modelHandler, your "hello world" application is up and running.

So what is the big deal of separation model interaction from model presentation. It might not be obvious for you right now. But here is a few things that I can think of. Firstly the separation can reduce code complexities to be manageable. As your application complexities grow, your code will grow linearly but not exponentially. You can add more view handlers to a view event to update more model, and add more model handler to model handler to update more views.

Secondly, the separation make each handler focus on one thing, so that code is more reliable, more testable. Yes, we can unit test our UI. I will cover that later. The idea is that we can test our view handler by triggering fake mouse event without a real mouse click. Because view is rendered by model handler, to test a view is to test model handler. We can test model handler by updating our model using via proxy.

Thirdly, you have a explicit, complete model, a single copy of logic, not a duplicated partial model distributed in spaghetti code. And the model can scale, you can add more model into different name space. The model the king of your UI, which rules the application. Different parts of model become shareable, and connected. The code become more easy to understand because of this.

There are other creative uses of viaProxy. For example, in our ajax callback, instead of update the UI directly, ajax callback update model using viaProxy, and your UI will be updated indirectly in a model handler. Instead of making ajax call directly in your view handler, your view handler can update model using proxy, that will trigger model handler, which will make the ajax call.

Through the "hello world" example, we can see that the design principle of viaProxy is to separate model interaction from model presentation. Essentially, it provides three following mechanisms to facilitate the separation.

  1. A proxy to build and access models
  2. An extensible model event mechanism to connect model to view
  3. An extensible view event mechanism (based on jQuery event) to connect view to model

Now that we know the design principle behind viaProxy, what is next. There are still lots of challenge. Does it work in a real world scenario or in large scale implementation, does it work with other existing controls or plugins, what if my model is complex object like array instead of simple string or number, is it extensible, how about validation, does it encapsulate too much or too little, is it too automatic, how easy is it to customize it, can I continue to use my programming style while using viaProxy, what about learning curve? I have considered all these when I develop the library, and I will discuss more in the future posts. Let me a comment, tell me what you think and stay tuned.

May 6, 2011

Semantics of undefined and null in javascript

Recently, I was discussing with a friend about the difference between undefined and null in javascript. I am surprised that I gave an explanation that he can understand, more surprisingly, I can understand too. Sometimes, people give an explanation, which they don't understand themselves, and also confuse others. Before going further, here is the explanation from JavaScript: The Definitive Guide

You might consider undefined to represent a system-level, unexpected, or error-like absence of value and null to represent program-level, normal, or expected absence of value. If you need to assign one of these values to a variable or property or pass one of these values to a function, null is almost always the right choice.

The explanation is confusing to me. What does this means in my daily coding, in what scenario I must use one but not the other or a scenario I can use either of them? So if null is almost the right choice, but why we have "undefined", is there any technical reason or semantic reason? Let's see why we have "undefined" value in javascript from technical perspective. When we write the following code, I can say, I declare two variables and they are not assigned with any value, and the default value of each is undefined.

var x;
var loooooooooooooooooooooooooong;

After reading the article Understand delete, I understand that, javascript variable mechanism. When you declared variable like above, you add a key/value pair entry to a mysterious object, VariableObject, which is dictionary. Here is pseudo code, that the engine will convert to

VariableObject["x"] = undefined;
VariableObject["loooooooooooooooooooooooooong"] = undefined;
//semantically, it means the following
//VariableObject.add("x", undefined);
//VariableObject.add("loooooooooooooooooooooooooong", undefined);

If the above example, two key/value pairs are added to the VariableObject dictionary. So both the key and value consume memory, so if you have a longer variable name, regardless its value, it use more memory than short variable. This is different from c++. In c++, a variable name is nick name of memory address. So practically, we should use shorter variable name, or use minifier to rename your variable. The VariableObject is special in that it is created by runtime. If the code is run in Global scope, the VariableObject is accessible as window. If it is run function scope, it is not accessible at all, which is known as Activation Object. Supposed it is run in global scope, it is same as the following.

window["x"] = undefined;
window["loooooooooooooooooooooooooong"] = undefined;

In the above case, variable x is said declared because its key is in the dictiobary, but its value is undefined. If the key is not even in the dictionary, then it is undeclared. Technically, there is difference between "undeclared" and "declared but undefined". But the following undefined check does not tell the difference.

//suggested by jQuery Code Style Guildeline
//http://docs.jquery.com/JQuery_Core_Style_Guidelines
//undefined check
//Global Variables: 
typeof variable === "undefined"
//Local Variables: 
variable === undefined
//Properties: 
object.prop === undefined

If you really need to know the difference, you need to use catch, because accessing undeclared variable directly will throw an exception.

function test(variableName) {
  try {
     var temp = eval(variableName);
    if (temp === undefined) {
       return "\"" + variableName + "\" is declared, its value is undefined"; 
    } else {
       return "\"" + variableName + "\" is declared, its value is not undefined"; 
    }
  } catch (e) {
      return "\"" + variableName + "\" is undeclared";
  }
}

var y;
var z = null;

alert(test("x")); // "x" is undeclared
alert(test("y")); // "y" is declared, its value is undefined
alert(test("z")); // "z" is declared, its value is not undefined

Most of time, we don't care the difference between undeclared and undefined. Practically, we can treat it the same, if a value is undefined, it does not exist in dictionary, although it is not quite true. If we accept this, we can use the undefined check as the jQuery code style guidline recommend.

Back to the question, why we need to have undefined? This is because variable is key/value entry in dictionary, this is because we can add entry into dictionary in runtime. If its value is undefined, practically it does not exist in the dictionary. Using null simply simply can express this semantics, because its value is "null", it is already in the dictionary. Now we know the techinicall difference, how can apply them into our coding. undefined check is normally used, before defining it. Here is an sample

//if somebody defined, if it has been defined, regardless its value,
//don't define it again.   
if (console.log === undefined ) {
    console.log = function () { ... }
  }


function css(key, value) {
  //if user does not give a value,
  //he want to get the value
  if (value === undefined) {
     return db[key];
  } else {
    //otherwise user want to set the value
   db[key] = value;
  }
}

But what about null in javascript? We know how technically it is different from undefined. What is its semantics? Short answer is it depends. It is up to you how to interpret it, and only you can define it in your application. In my matrix library, I use null to represent the case when no a resource has no dependencies, the undefined value to represetn the case when dependencies is yet to know, the semantics is quite different. But its semantics can be others if you want.

if (depedencies["x.js"] === undefined ) {
       //go figure out the what dependencies is and come back later

    } else if (depedncies["x.js"] === null) { 
       //there is no dependencies, load it directly.

    } else {
        //load dependencies["x.js"] first, because it is not empty.
   }

Mar 19, 2011

A enhanced curry method

JavaScript is a functional language, it supports function composition, we can do curry with JavaScript. Douglas Crockford has defined "curry" method in his book JavaScript: The Good Parts to facilitate the steps to define curried function.

Function.prototype.method = function ( name, func ) {
 if ( !this.prototype[name] ) {
  this.prototype[name] = func;
 }
};

Function.method( 'curry', function () {
 var slice = Array.prototype.slice,
   args = slice.apply( arguments ),
   that = this;
 return function () {
  return that.apply( null, args.concat( slice.apply( arguments ) ) );
 };
} );

//so I can write the following code

test( "test curry", function () {
 function cancat_abc( a, b, c ) {
  return a + b + c ;
 }

 var cancatBc = cancatAbc.curry( "a" );
 var result = cancatBc( "b", "c" );
 equal( result, "abc", "the first parameter is preloaded" );

} );


Nice. But there is problem here, the preloaded arguments have to be the first consecutive arguments. So if I have want to preload the second and third parameter. The curry method does not support that.


Of course, I can do it manually instead of using the curry method, but this is not quite DRY (Don't Repeat Yourself). So I modify the curry method as follow to do the work.


Function._ = {};

Function.method( 'curry', function () {
 var slice = Array.prototype.slice,
   preloads = slice.apply( arguments ),
   _ = Function._,
   fn = this;
 return function () {
  var args = slice.apply( arguments );
  for ( var i = 0; i < preloads.length; i++ ) {
   if ( preloads[i] == _ ) {
    preloads[i] = args.shift();
   }
  }

  return fn.apply( null, preloads.concat( args ) );
 };
} );

var _ = Function._;

test( "test curry", function () {
 ok( _, "an dummy object has been defined" );
 function cancat_abcd( a, b, c, d ) {
  return a + b + c + d;
 }

 var cancatBd = cancatAbc.curry( "a", _, "c", _ );
 var result = cancatBd( "b", "d" );
 equal( result, "abcd", "curry should work in order" );

} );

Dec 7, 2010

"this" in javascript

If you don't know javascript is a functional language and you do lots of object oriented programming, the follow code must be very confusing for you.

var name = "Jerry";

var x = { name : "Tom",
          sayName1 : function () {
              alert(this.name);
           },
          sayName2 : function () {
             sayName3();
           },
           sayName4 : function () {
            sayName3.call(this); 
          }
        };

var sayName3 = x.sayName1;  

x.sayName1(); //show Tom //line a
sayName3();   //show Tom? no, it is Jerry //line b 
x.sayName2(); //show Tom? no, it is still Jerry!! //line c
x.sayName4();  //now it is Tom //line d

In OO language like C#, java, instance method belongs to an instance(object). The method knows "this" is referring the instance it belongs to. So if you use this concept to apply to javascript, you will think the behavior line a make sense. Line b will be confusing, and line c and line d is even confusing. In javascript, object can reference function, however functions don't belong to any object, and a function does not know what "this" is, until is called in one of the following case. Let's read the follow code


var x = new ConstructorFunction();
var y = simpleCallFunction();
var z = o.memberCallFunction();
var a = usingapplyCallFunction.apply(o, [p1, p2]);
var b = usingcallCallFunction.call(o, p1, p2);

In line y, the "this" in simpleCallFunction always refer to global object. In line a,b, they are basically the same,except the syntax, which specify the object that "this" is referred to. In line z, we can rationalize at as " var temp = o.membershipCallFunction; temp.call(o); " or just "o.membershipCallFunction.call(o);". Line x is constructor call, the "this" is the object being created.


What the global object is depends on the engine. In browser, it refers the window object. But there are other environment too. Here is how window object is passed in? When a page is loading, javascript engine convert the string in <script /> block to a function, let's say, x, then call x.call(window). That is why all your code in the block knows that "this" is window. In line y, you can rationalize it as " simpleCallFunction.call(window) ". The only special case is line x, which use function as a constructor. So what happens to native javascript object, for example, array. If you want to use push method of an array for a non array method, can you? Yes, you can, in fact, that is why jQuery object works like an array even though it is not an array. Here is trick.


var fQuery = { push: [].push }
fQuery.push("item1");
//it works like an array!!
//push method does not belong to array, you can apply it to any object
alert(fQuery [0]);
alert(fQuery.length);

In conclusion, javascript function does not belong to any object, "this" is parameter passed in implicitly or explicitly during the function is called, "this" is just the same as other parameter. However, the language just provide some misleading syntax (but it is also good syntax) to pass the parameter into a function.

Nov 15, 2010

benchmark you javascript

Here is script that is used to benchmark jQuery.

// Runs a function many times without the function call overhead
function benchmark(fn, times, name){
 fn = fn.toString();
 var s = fn.indexOf('{')+1,
  e = fn.lastIndexOf('}');
 fn = fn.substring(s,e);
 
  return benchmarkString(fn, times, name);
}

function benchmarkString(fn, times, name) {
  var fn = new Function("i", "var t=new Date; while(i--) {" + fn + "}; return new Date - t")(times)
  fn.displayName = name || "benchmarked";
  return fn;
}

Nov 13, 2010

jQuery object is an array like object

jQuery object is not an Array object, but it looks like an array. The following code how this is implemented?

var o = {"0":1, "1": 2, length:2};
var a = [].slice.call(o, 0);
alert(a); // 1, 2


//or you can do this
var o = {}
o[0] = 1;
o.length = 1;
o[1] = 2;
o.length = 2;
var a = [].slice.call(o, 0);
alert(a); // 1, 2

//or you can do this
var o = {};
[].push.call(o, 1);
[].push.call(o, 2);
var a = [].slice.call(o, 0);
alert(a); // 1, 2

object toString

The memeber toString of different object is redefined in their prototype, for example, Object.prototype.toString is different from Array.prototype.toString, to apply a Object.prototype.toString to an array object, we can write the following code

var toString = Object.prototype.toString;
alert(toString.call([1, 2])); //[object Array]
alert([1, 2].toString()); //1,2

This will return the type of the object, "[object Array]"

using each function over "for" construct

jquery.each

jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});



Jul 6, 2010

an another way to do setInterval

In window object, there is a function setInterval which allows your to run a task repeatedly at an interval.


setInterval(doSomething; 100);

However, if the method last longer than the preset interval, it is not so efficient. We can use the follow function to make it more predictable.


loopTask(doSomething, 100);

function loopTask(fn, interval) {
   (function(){
       fn();
       setTimeout(arguments.callee, interval);
   })();
}

Jul 4, 2010

notes of regular expression in javascript

The simplest way to tell whether a regular expression is find in source string is to use the "test" method.


var reg = /a/;
var found = reg.test("abc");
console.log(found);

In lots of occasion, we use regular expression to test user's input, for example to test if a input is in date format. You need the "^" and "$" character to wrap the regular expression pattern.


To do a simple search in string, we can use string.match(regex) syntax. This is useful when we do want to whether a match or how many matchs can be found. If you just care about a first match, you will use non global regular expression. In this case, f a match is found, an array object will be return, the first element of the array is the entire match, the 1 to (length -1)th members of the array is the sub matches which are generated by the round bracket "()". The array or match object also has property "index" and "input". When a regular expression search is perform, the RegExp object also get updated.


var src = "Please send mail to george@contoso.com and someone@example.com. Thanks!";

// Create a regular expression to search for an e-mail address.
var re_non_global = /(\w+)@(\w+)\.(\w+)/;
var result = src.match(re_non_global);

for (var n in result)
{
  console.log(n + ":" + result[n]);
}
/*
0:george@contoso.com
1:george
2:contoso
3:com
index:20
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
*/

console.log("RegExp properties");
for(var n in RegExp)
{
  console.log(n + ":" + RegExp[n]);
}

/*
RegExp properties
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
multiline:false
lastMatch:george@contoso.com
lastParen:com
leftContext:Please send mail to
rightContext: and someone@example.com. Thanks!
$1:george
$2:contoso
$3:com
$4:
$5:
$6:
$7:
$8:
$9:
*/

If we care about more than the first match, we need to do a global search, we need global regular expression. When the match object return is also an array, sub-match is ignord. Each element in the array is a single match. The RegExp store the information of the last match.

var re_global = /(\w+)@(\w+)\.(\w+)/g;
// Because the global flag is included, the matches are in
// array elements 0 through n.
var result = src.match(re_global);
for (var n in result)
{
  console.log(n + ":" + result[n]);
}
/*
0:george@contoso.com
1:someone@example.com
*/

console.log("RegExp properties");
for(var n in RegExp)
{
  console.log(n + ":" + RegExp[n]);
}
/*
RegExp properties
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
multiline:false
lastMatch:someone@example.com
lastParen:com
leftContext:Please send mail to george@contoso.com and
rightContext:. Thanks!
$1:someone
$2:example
$3:com
$4:
$5:
$6:
$7:
$8:
$9:
*/


However string.match(regex) is less powerfull than regex.exec(string), which allow you exam each match object interactively, but to do this you need to turn on the global option of regular expression. Each time the exec method is called, it will continue from the position after the last match. Because of this, we can use while loop.


var src = "Please send mail to george@contoso.com and someone@example.com. Thanks!";
var re_global = /(\w+)@(\w+)\.(\w+)/g;

var match;
while(match = re_global.exec(src)){
  console.log("match is found");
//match is an array with two additional index, and input properties
//  for(var i=0, length = match.length; i >length; i++)
//  {
//    console.log(i + ":" + match[i]);   
//  } 
  
  for (var n in match) {
    console.log(n + ":" + match[n]);
  }

  console.log("RegExp properties");
  for(var n in RegExp)
  {
     console.log(n + ":" + RegExp[n]);
  }
}
​/*

match is found
0:george@contoso.com
1:george
2:contoso
3:com
index:20
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
  
RegExp properties
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
multiline:false
lastMatch:george@contoso.com
lastParen:com
leftContext:Please send mail to
rightContext: and someone@example.com. Thanks!
$1:george
$2:contoso
$3:com
$4:
$5:
$6:
$7:
$8:
$9:

match is found
0:someone@example.com
1:someone
2:example
3:com
index:43
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
  
RegExp properties
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
multiline:false
lastMatch:someone@example.com
lastParen:com
leftContext:Please send mail to george@contoso.com and
rightContext:. Thanks!
$1:someone
$2:example
$3:com
$4:
$5:
$6:
$7:
$8:
$9:
*/  



If the global option is not enabled for regular expression, each call to regex.match will start from the beginning of the test string, so that you can not use previous code to do a global search. The match is always the first match.



var src = "Please send mail to george@contoso.com and someone@example.com. Thanks!";

var re_non_global = /(\w+)@(\w+)\.(\w+)/;

var match = re_non_global.exec(src);

​for (var n in match) {
  console.log(n + ":" + match[n]);
}
/*
0:george@contoso.com
1:george
2:contoso
3:com
index:20
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
*/  
  
console.log("RegExp properties");
for(var n in RegExp)
{
   console.log(n + ":" + RegExp[n]);
}

/*
RegExp properties
input:Please send mail to george@contoso.com and someone@example.com. Thanks!
multiline:false
lastMatch:george@contoso.com
lastParen:com
leftContext:Please send mail to
rightContext: and someone@example.com. Thanks!
$1:george
$2:contoso
$3:com
$4:
$5:
$6:
$7:
$8:
$9:
​*/​;

If we want to replace match with our text, we can use str.replace(regexp|substr, newSubStr|function[, Non-standard flags]) method, we also make sure we turn on global option of the global expression, otherwise it will only replace the first match. We can use some special symbols inside newSubStr to do the replacing, for more See this. We can also use a function to return the string dynamically as replacement string. The function parameter is like the following, for more information see here.


//offset is the position of the match, source is 
function replacer($0, $1, $2, .. ,offset, source)
{ return your_new_string;}

May 19, 2010

Functional aspect of c#

Two generic delegate in c#, makes c# look more like a functional language, they are Action<T>, Func<T1, T2, ...>. The functional feature let you easily express your algorithm, without using the traditional design pattern. These delegates can be compared with function in javascript, and lamda in other language. For example,


interface IStrategy
{
   void Execute(object o);
}

Using design pattern, we have to write a more code to aggregate different strategies. But using Action<T> is more succinct.


Action<object> oldAction = ... ;//
Action<object> newAction = (o) => { Console.Write("preAction"); oldAction(o); Console.Write("postAction"); }
newAction(o);

If we want to go a step further, we can use function(lamda, delegate) to create functions. For example:


Func<Action<object>, Action<object>> createFunc = (func) => 
{
   return (o) => { 
             Console.Write("preAction"); 
             func(o); 
             Console.Write("postAction"); 
          };
}

Action<ojbect> newAction = createFunc(oldAction);
newAction(o);

Functional language is not new, Javascript is a functional language, and it has been doing this for a long long time. The power functional programming is that you can easily define new function easily, so that you can get interesting result of the new function.

May 15, 2010

Return statement in javascript

return expression;
//or
return;

If there is no expression, then the return value is undefined. Except for constructor, whose return value is this

Throw error

//"throw" is not limited just throwing Error, basically, you can throw anything.

//but normally, you are supposed to 

throw new Error(reason);
//or
throw {name: exceptionName, message:reason};

Array in javascript

Technically, array in javascript is not really array in the context of other language like c#, it is more like a dictionary, the index is actually used as a key of an entry in the dictionary, like to the following.

var a = [];
a[0] = "fred";
alert(a["0"] == a[0]);

It is unique in that it has a length property, when you push an new item, array can automatically increase its length. It is also unique in that it support traditional for statement like for (i=1; i< a.length; i++) { ... }. Because Array is also an object so we can also use statement like "for ( var i in x), but it is not recommended because it defeat the purpose of array.



On the other hand, we can simulate the array feature for normal object. jQuery also use the technique like the following, so that jQuery object looks like an object, but it is not.


var push = [].push;
var y = {};
push.call(y, 100);
alert(y.length); //1
alert(y[0]); //100
​

To delete an array, do not use "delete array[index]" use array.splice(index, 1);

supplant function

var template = '<table border="{border}">' +
    '<tr><th>Last</th><td>{last}</td></tr>' +
    '<tr><th>First</th><td>{first}</td></tr>' +
    '</table>';
    

var data = { first: "Carl", last: "Hollywood", border: 2 };

mydiv.innerHTML = template.supplant(data);

if (typeof String.proptotype.supplant !== 'function')
{
     String.prototype.supplant = function (o) {
        return this.replace(/{([^{}]*)}/g, 
                function(a, b) {
                  //a is $0, b is $1 (match 1)
                   var r = o[b];
                   return typeof r === 'string' ? r : a;
                });
    };
}