Tag Archive : programming

/ programming

NodeJS Streams, Pump, and Pipe

December 9, 2015 | Article | 1 Comment

Stream is an object that represents a generic sequence of bytes. Any type of data can be stored as a sequence of bytes, so the details of writing and reading data can be abstracted.

Node has a useful abstraction for stream. More specifically, two very abstractions: Read Streams and Write Streams. They are implemented throughout several Node objects, and they represent inbound (ReadStream) or outbound (WriteStream) flow of data.

Though read and write operation on stream is not special in any programming language, Node has unique way to do it.

ReadStream

A ReadStream is like a faucet of data. The method of creating streams are depends on the type of stream itself. After you have created a one, you can: wait for data, know when it ends, pause it, and resume it.

Wait for data

By binding to the “data” event we can be notified every time there is a chunk being delivered by that stream. It can be delivered as a buffer or as a string.
If we use stream.setEncoding(encoding), the “data” events pass in strings. If we don’t set an encoding, the “data” events pass in buffers.

var readStream = ...
readStream.on('data', function(data) {
    // data is a buffer
});

var readStream = ...
readStream.setEncoding('utf8');
readStream.on('data', function(data) {
    // data is utf8-encoded string
});

So here data passed in on the first example is a buffer, and the second one is a string because we specify it as utf8 string.

The size of each chunk may vary, it may depend on buffer size or on the amount of available data so it might unpredictable.

Know when it ends

A stream can end, and we can know when that happens. By binding to the “end” event, we can see it.

var reasStream = ...
readStream.on('end', function() {
    console.log('the stream has ended');
});

Pause

A read stream is like a faucet, and we can keep the data from coming in by pausing it.

readStream.pause();

Resume

If stream is paused, we can reopen it and the stream can start flowing again.

readStream.resume();

WriteStream

A WriteStream is an abstraction on somewhere you can send data to. It can be a file or network connection or even an object that outputs data that was transformed.

When we have WriteStream object, we can do two operations: write and wait for it to drain.

Write

We can write data to stream. The data can be in string format or a buffer format.

By default, write operation will treat a stirng as utf8 string unless it is told otherwise.

var writeStream = ...;

writeStream.write('this is an utf-8 string');
writeStream.write('7e3e4acde5ad240a8ef5e731e644fbd1', 'base64');

For writing a buffer, we can slightly modify it to

var writeStream = ...;
var buffer = new Buffer('this is a buffer with some string');
writeStream.write(buffer);

Wait for it to drain

Node does not block on I/O operation, so it does not block on read or write commands. On write commands, if Node is not able to flush the data into the kernel buffers, it will buffer that data, storing it in our process memory. Because of this, writeStream.write() returns a boolean. If write() manages to flush all data to the kernel buffer, it returns true. If not, it returns false.

When a writeStream manages to do flush the data into the kernel buffers, it emits a “drain” event so we can listen it like this:

var writeStream = ...;
writeStream.on('drain', function() { console.log('drain emitted'); });

Stream by Example

FileSystem stream

We can create a read stream for a file path.

var fs = require('fs');

var rs = fs.createReadStream('/path/to/file');

We can also pass some options for .createReadStream(), for example: start and end position of file, the encoding, the flags, and the buffer size. Below is the default value of option:

{
    flags: 'r',
    encoding: null,
    fd: null,
    mode: 0666,
    bufferSize: 64*1024
}

We can also create a write stream

var fs = require('fs');
var rs = fs.createWriteStream('/path/to/file', options);

Which also accepts a second argument with an option object. Below is the default value of option:

{
    flags: 'w',
    encoding: null,
    mode: 0666
}

We can also give a single specification if it is necessary.

var fs = require('fs');
var rs = fs.createWriteStream('/path/to/file', {encoding: 'utf8'});

Case Study: Slow Client Problem

As said before, Node does not block on writes, and it buffers the data if the write cannot be flushed into the kernel buffers. Now if we are pumping data into a write stream (like a TCP connection to a browser) and our source of data is a read stream (like a file ReadStream):

var fs = require('fs');

require('http').createServer(function(req, res) {
   var rs = fs.createReadStream('/path/to/big/file');
   rs.on('data', function(data) {
      res.write(data);
   });
   rs.on('end', function() {
      res.end();
   });
});

If the file is local, the read stream should be fast. Now if the connection to the client is slow, the writeStream will be slow. So readStream “data” events will happen quickly, the data will be sent to the writeStream, but eventually Node will have to start buffering the data because the kernel buffers will be full.

What will happen then is that the /path/to/big/file file will be buffered in memory for each request, and if we have many concurrent requests, Node memory consumption will inevitably increase, which may lead to other problems, like swapping, thrashing and memory exhaustion.

To address this problem we have to make use of the pause and resume of the read stream, and pace it alongside your write stream so your memory does not fill up:

var fs = require('fs');

require('http').createServer(function(req, res) {
   var rs = fs.createReadStream('/path/to/big/file');
   rs.on('data', function(data) {
      if(!res.write(data)) {
         rs.pause();
      }
   });
   res.on('drain', function() {
      rs.resume();
   });
   rs.on('end', function() {
      res.end();
   });
});

We are pausing the readStream if the write cannot flush it to the kernel, and we are resuming it when the writeSTream is drained.

Pump

What was described here is a recurring pattern, and instead of this complicated chain of events we can simply use util.pump() which does exactly what we described:

var util = require('util');
var fs = require('fs');

require('http').createServer(function(req, res) {
    var rs = fs.createReadStream('/path/to/big/file');
    util.pump(rs, res, function() {
        res.end();
    });
});

util.pump() accept 3 argumens: the readable stream, the writable stream, and a callback when the read stream ends.

Pipe

There is another approach we can use, pipe. A ReadStream can be piped into a WriteStream on the same fashion, simply by calling pipe(destination).

var fs = require('fs');

require('http').createServer(function(req, res) {
    var rs = fs.createReadStream('/path/to/big/file');
    rs.pipe(res);
});

By default, end() is called on the destination when the read stream ends. We can prevent that behavior by passing in end: false on the second argument options object like this:

var fs = require('fs');

require('http').createServer(function(req, res) {
    var rs = fs.createReadStream('/path/to/big/file');
    rs.pipe(res, {end: false});
    rs.end(function() {
        res.end("And that's all folks!");
    });
});

Creating Own Read and Write Streams

We can implement our own read and write streams.

ReadStream

When creating a Readable stream, we have to implement following methods:

  • setEncoding(encoding)
  • pause()
  • resume()
  • destroy()

and emit the following events:

  • “data”
  • “end”
  • “error”
  • “close”
  • “fd” (not mandatory)

We should also implement the pipe() method, but we can lend some help from Node by inheriting from Stream.

var MyClass = ...
var util = require('util'),
    Stream = require('stream').Stream;
util.inherits(MyClass, Stream);

This will make the pipe method available at no extra cost.

WriteStream

To implement our own WriteStream-ready pseudo-class we should provide the following methods:

  • write(string, encoding=’utf8′, [fd])
  • write(buffer)
  • end()
  • end(string, encoding)
  • end(buffer)
  • destroy()

and emit the following events:

  • “drain”
  • “error”
  • “close”

NodeJS HTTP

December 9, 2015 | Article | 1 Comment

HTTP or Hyper Text Transfer Protocol is an application protocol for distributed, collaborative, hypermedia information systems. It is the protocol which become the foundation of data communication for the World Wide Web.

HTTP in most case is using client-server architecture. It means there are one (or more) server which can serve several client.

NodeJS has abstract HTTP behavior in a way we can use it for building scalable application.

HTTP Server

Using Node, we can easily create an HTTP server. For example:

var http = require('http');

var server = http.createServer();
server.on('request', function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write('Hello World!');
    res.end();
});
server.listen(4000);

We have ‘http’ module, which is a further encapsulation of what ‘net’ module does for HTTP protocol.

Every server should bind and listen to an arbitrary port. In our example, our server listen to port 4000. The server is handling an event request for HTTP server. This event is triggered when a client is request or connecting to our server. We set callback which has two arguments: request and response.

Our callback will have two object, in our example are req (request) and res (response). A request is object which encapsulate all request data sent to our server. A response is object which we will sent back to the client. Here, when we are requested by client, we will write a response. That’s what HTTP does, as simple as that.

A response is composed of two field: header and body. We write the header with the content-type which indicate a plain text. In the body, we have a string ‘Hello World!’.

If you run this script on node, you can then point your browser to http://localhost:4000 and you should see the “Hello World!” string on it.

We can shorten the example to be:

require('http').createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World!');
}).listen(4000);

Here we are giving up the intermediary variable for storing the http module (since we only need to call it once) and the server (since we only need to make it listen on port 4000). Also, as a shortcut, the http.createServer function accepts a callback function that will be invoked on every request.

Request Object

Request object (first argument of the callback) is an instantiation of http.ServerRequest class. It has several important aspect which we can see.

.url

This is the URL of the request. It does not contain schema, hostname, or port, but it contains everything after that.

We can try to analyze the url by:

require('http').createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(req.url);
}).listen(4000);

The URL are the resource requested by client. For example:

  • http://localhost:4000/ means the URL requested is /
  • http://localhost:4000/index.html means the URL requested is /index.html
  • http://localhost:4000/controller/index.js means the URL requested is /controller/index.js
  • etc

.method

This contains the HTTP method used on the request. It can be ‘GET’, ‘POST’, ‘DELETE’, or any valid HTTP request method.

.headers

This contains an object with a property for every HTTP header on the request.

We can analyze the headers by:

require('http').createServer(function(req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(util.inspect(req.headers));
}).listen(4000);

req.headers properties are on lower-case. For instance, if the browser sent a “Cache-Control: max-age: 0” header, reg.headers will have a property named “cache-control” with the value “max-age: 0” (this last one is untouched).

Response Object

Response object is the second argument for callback. It is used to reply the request to the client and an instantiation of http.ServerResponse class.

Write Header

A response is like request, composed of header and body. The header contains a property for every header we want to send. We can use res.writeHead(status, headers) to write the header.

For example:

var util = require('util');

require('http').createServer(function(req, res) {
    res.writeHead(200, {
        'Content-Type': 'text/plain',
        'Cache-Control': 'max-age=3600'
    });
    res.end('Hello World!');
}).listen(4000);

On this example, we set 2 headers: one with “Content-Type: text/plain” and another with “Cache-Control: max-age=3600”.

Change or Set a Header

We can change a header which already set or set a new one by using.

res.setHeader(name, value);

This will only work if we haven’t already sent a piece of the body by using res.write().

Remove a Header

We can also remove a hader we already set by using.

res.removeHeader(name, value);

This will only work if we haven’t already sent a piece of the body by using res.write().

Write Response Body

To write a response, we can use:

// write a simple string
res.write('Here is string');

// existing buffer
var buf = new Buffer('Here is buffer');
buf[0] = 45;
res.write(buffer);

This method can, as expected, be used to reply dynamically generated strings or binary file.

HTTP Client

Creating http client using node is also possible and easy. The same module ‘http’ can be used to create HTTP client, even though it is specifically designed to be a server.

.get()

HTTP GET is a simple request to the url.

In this example, we sent HTTP GET request to the url http://www.google.com:80/index.html.

var http = require('http');

var options = {
  host: 'www.google.com',
  port: 80,
  path: '/index.html'
};

http.get(options, function(res) {
  console.log('got response: ' + res.statusCode);
}).on('error', function(err) {
  console.log('got error: ' + err.message)
});

.request()

Using http.request, we can make any type of HTTP request (not limited to HTTP GET only).

http.request(options, callback);

The options is an object which describe the host we want to connect to. It is composed of:

  • host: a domain name or IP address of the server to issue the request to
  • port: Port of remote server
  • method: a string specifying the HTTP request method. Possible values: GET, POST, PUT, DELETE
  • path: Request path. It should include query string and fragments if any. E.G. ‘/index.html?page=12’
  • headers: an object containing request headers.

For example:

var options = {
    host: 'www.google.com',
    port: 80,
    path: '/upload',
    method: 'POST'
};

var req = require('http').request(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      console.log('BODY: ' + chunk);
    });
});

// write data to request body
req.write('data ');
req.write('data ');
req.end();

We are writing the HTTP request body data (two lines with the “data ” string with req.write()) and ending the request immediately. Only then the server replies and the response callback gets activated.

We wait for response. When it comes, we get a ‘response’ event, which we are listening to on the callback function. By then we only have the HTTP status and headers ready, which we print.

Then we bind to ‘data’ events. These data happen when we get a chunk of the response body data.

This mechanism can be used to stream data from a server. As long as the server keeps sending body chunks, we keep receiving them.

NodeJS Low Level File System Operation

December 9, 2015 | Article | 1 Comment

Node has a nice streaming API for dealing with files in an abstract way, as if they were network streams. But sometimes, we might need to go down a level and deal with the filesystem itself. Node has facilitate this by providing a low-level file system operation, using module fs.

Get File Metainfo

A metainfo is information about information of a file or directory. In POSIX API, we use stat() and fstat() function to do this. Node, which is inspired by POSIX, has taken this approach too. The stat() and fstat() has been encapsulated to fs module.

var fs = require('fs');

fs.stat('file.txt', function(err, stats) {
    if (err) { console.log (err.message); return }
    console.log(stats);
});

Here we need a fs module and do stat(). A callback is set with two arguments, first is for get the error message if there is an error occurred, and second is the stat information if the function succeeded.

If succeeded, the callback funtion might print something like this (result taken on Cygwin64 on Windows 8):

{ dev: 0,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  ino: 0,
  size: 2592,
  atime: Thu Sep 12 2013 19:25:05 GMT+0700 (SE Asia Standard Time),
  mtime: Thu Sep 12 2013 19:27:57 GMT+0700 (SE Asia Standard Time),
  ctime: Thu Sep 12 2013 19:25:05 GMT+0700 (SE Asia Standard Time) }

stats is Stats instance, an object, which we cal call some methods of it.

stats.isFile();
stats.isDirectory();
stats.isBlockDevice();
stats.isCharacterDevice();
stats.isSymbolicLink();
stats.isFIFO();
stats.isSocket();

If we have a plain file descriptor, we can use fs.fstat(fileDescriptor, callback) instead.

If using low-level filesystem API in node, we will get file descriptors as a way to represent files. These file descriptors are plain integer numbers given by kernel that represent a file in Node process. Much like C POSIX APIs.

Open and Close a File

Opening a file is a simple matter by using fs.open()

var fs = require('fs');
fs.open('path/to/file', 'r', function(err, fd) {
    // got file descriptor (fd)
});

It’s like C function, if you are familiar with.

The first argument to fs.open is the file path. The second argument is the flags, which indicate the mode with which the file is to be open. The valid flags can be ‘r’, ‘r+’, ‘w’, ‘w+’, ‘a’, or ‘a+’.

  • r = open text file for reading. The stream is positioned at the beginning of the file.
  • r+ = open for reading and writing. The stream is positioned at the beginning of the file.
  • w = truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.
  • w+ = open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.
  • a = open for writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subsequent writes to the file will always end up at the current end of file.
  • a+ = open for reading and writing. The file is created if it does not exist. The stream is positioned at the end of the file. Subsequent writes to the file will always end up at the current end of file.

On the callback function, we get the file descriptor or fd as second argument. It is a handler to read and write the file which is opened by fs.open() function.

After operation, it is recommended to close the opened file using fs.close(fd).

Read From a File

Once it’s open, we can read from a file but make sure we have set the mode to allow us read it.

var fs = require('fs');
fs.open('file.txt', 'r', function(err, fd) {
   if (err) { throw err; }
   var readBuffer = new Buffer(1024),
      bufferOffset = 0,
      bufferLength = readBuffer.length,
      filePosition = 100;

   fs.read(fd, readBuffer, bufferOffset, bufferLength, filePosition,
      function(err, readBytes) {
         if (err) { throw err; }
         console.log('just read ' + readBytes + ' bytes');
         if (readBytes > 0) {
            console.log(readBuffers.slice(0, readBytes));
         }
   });
});

Here we open the file, and when it’s opened we are asking to read a chunk of 1024 bytes from it, starting at position 100 (so basically, we read data from bytes 100 to 1124).

A callback is called when one of the following three happens:

  • there is an error
  • something has been read
  • nothing could be read

If there is an error, the first argument of callback – err – will be set. Otherwise, it is null.

The second argument of callback – readBytes – is the number of bytes read into the buffer. If the read bytes is zero, the file has reached the end.

Write Into a File

Once file is open, we can write into a file but make sure we have set the mode to allow us read it.

var fs = require('fs');
fs.open('file.txt', 'a', function(err, fd) {
   if (err) { throw err; }
   var writeBuffer = new Buffer('Writing this string'),
      bufferOffset = 0,
      bufferLength = writeBuffer.length,
      filePosition = null;

   fs.write(fd, writeBuffer, bufferOffset, bufferLength, filePosition,
      function(err, written) {
         if (err) { throw err; }
         console.log('wrote ' + written + ' bytes');
   });
});

Here we open the file with append-mode (‘a’), and we are writing into it, starting at position 0. We pass in the buffer with data we want to written, an offset inside the buffer where we want to start writing from, the length of what we want to write, the file position and a callback.

In this case we are passing in a file position of null, which is to say that we writes at the current file position. As noted before, we open the file using append-mode, so the file cursor is positioned at the end of the file.

Case on Appending

If you are using these low-level file-system functions to append into a file, and concurrent writes will be happening, opening it in append-mode will not be enough to ensure there will be no overlap. Instead, you should keep track of the last written position before you write, doing something like this:

var fs = require('fs');

var startAppender = function(fd, startPos) {
   var pos = startPos;
   return {
      append: function(buffer, callback) {
         var oldPos = pos;
         pos += buffer.length;
         fs.write(fd, buffer, 0, buffer.length, oldPos, callback);
      }
   };
}

Here we declare a function stored on a variable named “startAppender”. This function starts the appender state (position and file descriptor) and then returns an object with an append function.

To use the Appender:

fs.open('file.txt', 'w', function(err, fd) {
   if (err) { throw err; }
   var appender = startAppender(fd, 0);
   appender.append(new Buffer('append this!'), function(err) {
      console.log('appended');
   });
});

And here we are using the appender to safely append into a file.

This function can then be invoked to append, and this appender will keep track of the last position, and increments it according to the buffer length that was passed in.

Actually, there is a problem: fs.write() may not write all the data we asked it to, so we need to modify it a bit.

var fs = require('fs');

var startAppender = function(fd, startPos) {
    var pos = startPos;
    return {
        append: function(buffer, callback) {
            var written = 0;
            var oldPos = pos;
            pos += buffer.length;
            (function tryWriting() {
                if (written < buffer.length) {
                    fs.write(fd, buffer, written, buffer.length - written,
                             oldPos + written, 
                        function(err, bytesWritten) {
                            if (err) { callback(err); return; }
                            written += bytesWritten;
                            tryWriting();
                        }
                    );
                } else {
                   // we have finished
                   callback(null);
                }
            })();
        }
    }
};

Here we use a function named “tryWriting” that will try to write, call fs.write, calculate how many bytes have already been written and call itself if needed. When it detects it has finished (written == buffer.length) it calls callback to notify the caller, ending the loop.

Also, the appending client is opening the file with mode “w”, which truncates the file, and it’s telling appender to start appending on position 0. This will overwrite the file if it has content. So, a wizer version of the appender client would be:

fs.open('file.txt', 'a', function(err, fd) {
   if (err) { throw err; }
   fs.fstat(fd, function(err, stats) {
      if (err) { throw err; }
      console.log(stats);
      var appender = startAppender(fd, stats.size);
      appender.append(new Buffer('append this!'), function(err) {
         console.log('appended');
      });
   })
});

NodeJS Timers

December 9, 2015 | Article | No Comments

A timer is a specialized type of clock for measuring time intervals. It is used for deploying routine action.

Node implements the timers API which also found in web browsers.

setTimeout

setTimeout let us to schedule an arbitrary function to be executed in the future. For example:

var timeout = 2000;    // 2 seconds
setTimeout(function() {
    console.log('time out!');
}, timeout);

The code above will register a function to be called when the timeout expires. As in any place in JavaScript, we can pass in an inline function, the name of a function or a variable which value is a function.

If we set the timeout to be 0 (zero), the function we pass gets executed some time after the stack clears, but with no waiting. This can be used to, for instance schedule a function that does not need to be executed immediately. This was a trick sometimes used on browser JavaScript. Another alternative we can use is process.nextTick() which is more efficient.

clearTimeout

A timer schedule can be disabled after it is scheduled. To clear it, we need a timeout handle which is returned by function setTimeout.

var timeoutHandle = setTimeout(function() { 
    console.log('Groaaarrrr!!!');
}, 1000);
clearTimeout(timeoutHandle);

If you look carefully, the timeout will never execute because we clear it just after we set it.

Another example:

var timeoutA = setTimeout(function() {
    console.log('timeout A');
}, 2000);

var timeoutB = setTimeout(function() {
    console.log('timeout B');
    clearTimeout(timeoutA);
}, 1000);

Which timeoutA will never be executed.

There are two timers above, A with timeout 2 seconds and B with timeout 1 second. The timeoutB (which fires first) unschedule timeoutA so timeout never executes and the program exits right after the timeoutB is executed.

setInterval

Set interval is similar to set timeout, but schedules a given function to run every X seconds.

var period = 1000; // 1 second
var interval = setInterval(function() {
  console.log('tick');
}, period);

That code will indefinitely keep the console logging ‘tick’ unless we terminate Node.

clearInterval

To terminate schedule set by setInterval, the procedure we do is similar to what we did to setTimeout. We need interval handler returned by setInterval and do it like this:

var interval = setInterval(...);
clearInterval(interval);

process.nextTick

A callback function can also be scheduled to run on next run of the event loop. To do so, we use:

process.nextTick(function() {
    // This runs on the next event loop
    console.log('yay!');
});

This method is preferred to setTimeout(fn, 0) because it is more efficient.

On each loop, the event loop executes the queued I/O events sequentially by calling associated callbacks. If, on any of the callbacks you take too long, the event loop won’t be processing other pending I/O events meanwhile (blocking). This can lead to waiting customers or tasks. When executing something that may take too long, we can delay execution until the next event loop, so waiting events will be processed meanwhile. It’s like going to the back of the line on a waiting line.

To escape the current event loop, we can use process.nextTick() like this:

process.nextTick(function() {
    // do something
});

This will delay processing that is not necessary to do immediately to the next event loop.

For instance, we need to remove a file, but perhaps we don’t need to do it before replying to the client. So we could do something like this:

stream.on('data', funciton(data) {
    stream.end('my response');
    process.nextTick(function() {
        fs.unlink('path/to/file');
    });
});

Let’s say we want to schedule a function that does some I/O – like parsing a log file -to execute periodically, and we want to guarantee that no two of those functions are executing at the same time. The best way is not to use a setInterval, since we don’t have that guarantee. the interval will fire no matter if the function has finished it’s duty or not.

Supposing there is an asynchronous function called “async” that performs some IO and that gets a callback to be invoked when finished, and we want to call it every second:

var interval = 1000;
setInterval(function() {
    async(function() {
        console.log('async is done');
    }
}, interval);

If any two async() calls can’t overlap, it is better off using tail recursion like this:

var interval = 1000;
(function schedule() {
    setTimeout(function() {
        async(function() {
            console.log('async is done!');
            schedule();
        });
    }, interval);
})();

Here we declare schedule() and invoking it immediately after we are declaring it.

This function schedules another function to execute within one second. The other function will then call async() and only when async is done we schedule a new one by calling schedul() again, this time inside the schedule function. This way we can be sure that no two calls to async execute simultaneously in this context.

The difference is that we probably won’t have async called every second (unless async takes to time to execute), but we will have it called 1 second after the last one finished.

NodeJS Event Emitter

December 9, 2015 | Article | No Comments

Many objects can emit events, in NodeJS of course. For instance a TCP server can emit a ‘connect’ event every time a client connects, or a file stream request can emit a ‘data’ event.

Connecting an Event

One can listen for events. If you are familiar with other event-driven programming, you will know that there must be a function or method “addListener” where you have to pass a callback. Every time the event is triggered, for example ‘data’ event is triggered every time there is some data available to read, then your callback is called.

In NodeJS, here is how we can achieve that:

var fs = require('fs');      // get the fs module
var readStream = fs.createReadStream('file.txt');
readStream.on('data', function(data) {
    console.log(data);
});
readStream.on('end', function(data) {
    console.log('file ended');
});

Here on readStream object we are binding two event: ‘data’ and ‘end’. We pass callback function to handle each of these cases. All are available uniquely to handle events from readStream object.

We can either pass in an anonymous function (as we are doing here), or a function name for a function available on the current scope, or even a variable containing a function.

Only Connect Once

There is a case where we only want to handle an event once and the rest we give up for it. It means, we only interests in first event only. We want to listen for event exactly once, no more or less.

There are two ways to do it: using .once() method or make sure we remove the callback once we are called.

The first on is the simplest way. We use .once() to tell NodeJS that we are only interested in handling first event occurred.

object.once('event', function() {
    // Callback body
});

Other way is

function evtListener() {
    // Function body
    object.removeListener('event', evtListener);
}
object.on('event', evtListener);

Here we use removeListener() which will be discussed more in next section.

On two above samples, make sure you pass appropriate callback i.e. providing appropriate argument number. The event also should be specified.

Removing Callback from Certain Event

Though we have use it in previous section, we will discuss it again here.

To remove a callback we need the object in which we will remove the callback from it and also the event name. Note that this is a pair which we should provide. We can’t provide only one of it.

function evtListener() {
    // Function body
    object.removeListener('event', evtListener);
}
object.on('event', evtListener);

The removeListener belongs to the EventEmitter pattern. It accepts the event name and the function is should remove.

Removing All Callback from Certain Event

If you ever need to, removing all listener for an event from an Event Emitter is possible. We can use:

object.removeAllListener('event');

Creating Self-Defined Event

One can use this Event-Emitter patter throughout application. The way we do is creating a pseudo-class and make it inherit from the EventEmitter.

var EventEmitter = require('events').EventEmitter,
    util         = require('util');

// Here is the MyClass constructor
var MyClass = function(option1, option2) {
    this.option1 = option1;
    this.option2 = option2;
}

util.inherits(MyClass, EventEmitter);

util.inherits() is setting up the prototype chain so that we get the EventEmitter prototype methods available on MyClass instance.

That way, instances of MyClass can emit events:

MyClass.prototype.someMethod = function() {
    this.emit('custom event', 'some arguments');
}

Which emitting an event named ‘custom event’, sending also some data (in this case is “some arguments”).

A clients of MyClass instance can listen to “custom events” event by:

var myInstance = new MyClass(1,2);
myInstance.on('custom event', function() {
    console.log('got a custom event!');
});

NodeJS Buffers

December 9, 2015 | Article | No Comments

Natively, JavaScript is not very good at handling binary data. Therefore, NodeJS adds a native buffer implementation and still using JavaScript’s way to manipulate it. The class here is the standard way in Node to transport data.

Generally, buffer can be passed on every Node API which require data to be sent. Also, when receiving data on a callback, we get a buffer (except when we specify stream encoding, in which we get a string).

Create a Buffer

The default encoding format in NodeJS is UTF-8. To create a Buffer from UTF-8 string, we can do:

var buff = new Buffer('Hello World');

A new buffer can also be created from other encoding format. As long as we specify the encoding format in second argument, there is no problem:

var buf = new Buffer('8b76fde713ce', 'base64');

Accepted encodings are: “ascii”, “utf8”, and “base64”.

We can also create a new empty buffer by specify the size:

var buf = new Buffer(1024);

Accessing Buffer

Accessing a buffer is like accessing an array of string. We use [] to access individual ‘character’.

buf[20] = 127;   // Set byte 20 to 127

Format Conversion

A data held on a buffer using an encoding format can be converted to other encoding format.

var str  = buf.toString('utf8');     // UTF-8
var str1 = buf.toString('base64');   // Base64
var str2 = buf.toString('ascii');    // ASCII

When you don’t specify the encoding, Node will assume we are going to use UTF-8. If you need specific encoding, pass it as the argument.

Slice a Buffer

A buffer can be sliced into a smaller buffer by using the appropriately named slice() method.

var buffer = new Buffer('A buffer with UTF-8 encoded string');
var slice = buffer.slice(10,20);

On above code, we slice the original buffer that has 34 bytes into a new buffer that has 10 bytes equal to the 10th to 20th bytes of original buffer.

Note that the slice function does not create new buffer memory, it uses the original untouched buffer underneath.

Copy from Buffer

We can copy a part of a buffer into another pre-allocated buffer by:

var buffer = new Buffer('A buffer with UTF-8 encoded string');
var slice = new Buffer(10);
var targetStart = 0,
    sourceStart = 10,
    sourceEnd = 20;

buffer.copy(slice, targetStart, sourceStart, sourceEnd);

It should be self-explained. Here we copy part of buffer into slice, but only data on positions 10 through 20.

NodeJS Utilities: About I/O and Debugging

December 9, 2015 | Article | No Comments

Utilities, like implied by the name, is utilities employed for some distinct purpose. These utilities are provided by NodeJS through global objects.

console

Node provides a global “console” object to which we can output strings. However, the output is classified into some mode, according to the output stream it print the output to.

.log()

If you want to print data to stdout, it’s as simple as writing following code:

console.log("Hello World!");

Which will print “Hello World!”. The data (string in that case) is streamed out after formatting it. It is mainly used for simple output and instead of string we can also output an object, like this:

var a = {1: true, 2: false};
console.log(a);    // => {'1': true, '2': false}

We can also use string interpolation to print out things, like:

var a = {1: true, 2: false};
console.log('This is a number: %d, and this is a stirng: %s, ' +
            'and this is an object outputted as JSON: %j',
            42, 'Hello', a);

Which in turns print:

This is a number: 42, and this is a stirng: Hello, and this is an object outputted as JSON: {"1": true, "2": false}

If you are familiar with C or C++, you might find it similar with C’s printf() function. The placeholder is similar, you use %d for number (integer and floating point number), %s for string, and %j for JSON which is not exists in C’s formatting.

.warn()

If you want to print out to stderr, you can do this:

console.warn("Warning!!");

.trace()

And to print stack trace, you can do:

console.trace();

For stack trace, you will be presented by the current stack condition.

util

util is a module, which bundles some functions. To use this module, we need to include the util module:

var util = require('util');

.log()

var util = require('util');
util.log('Hello');

Similar to console.log(), however it’s slightly different. The util.log() will print current timestamp and given string in which build a line like this: Mar 17:11:09 – Hello

.inspect()

There is also a handy function, inspect(), which is nice for quick debugging by inspecting and printing an object properties.

var util = require('util');
var a = {1: true, 2: false};
console.log(util.inspect(a));

We can give more arguments to util.inspect() which are in following format:

util.inspect(object, showHidden, depth = 2, showColors);

showHidden is argument which inspect non-enumerable properties if it is turned on. This properties are belong to the object prototype chain, not the object itself. The depth, third argument, is the default depth on the object graph it should show. This is useful when inspecting large objects. To recurse indefinitely, pass a null value.

An important note: util.inspect keeps track of the visited objects. If there is a circular dependencies, a string “[Circular]” will appear on the outputted string.

Function in JavaScript

December 9, 2015 | Article | 4 Comments

Every programming language (except Assembly) has function.

Function is a block of code (enclosed by curly-bracket) which can be executed when “someone” calls it.

Like a variable, function can be defined anywhere in the code.

There are several ways of defining function in JavaScript:

  • Function Declaration
  • Function Expression
  • Function as a result of new Function call

Function Declaration

Basically, a function has a name a function name followed by parenthesis and list of arguments inside. After that is a block of code enclosed by curly-bracket.

function function_name(list of argument) {
some code to be executed
}

The code inside the function will be executed when the function is called. It can be called directly when an event occurs (like when a user clicks a button), or by another function.

Arguments are optional. You can have 1 or more arguments supplied to function. Of course you can have function which don’t have any argument.

An example function:

function greet(name) {
    alert("Hello "+name);
}

Note that a keyword function in the beginning is a must.

To call a function, we can use following (call greet() function):

greet("Xathrya");

If you have function with argument, make sure when you call it you supply the correct argument.

Function declarations are parsed at pre-execution stage, when the browser prepares to execute the code. That’s why, both of these codes work:

//-- 1
function greet(name) {
  alert("Hello "+name)
}

greet("Xathrya")

//-- 2
greet("Xathrya")

function greet(name) {
  alert("Hello "+name)
}

And a function can be declared anywhere in the code, even in the scope of branching and repetition.

Function Expression

A function in JavaScript is a first-class value, just like a number or string. As we remember that JavaScript is loose in type system.

Anywhere where you could put a value, you can also put a function, declared “at place” with a function expression syntax: function(arguments) { ... }. No function name, as the function name will take the name of variable. Therefore we can have:

var f = function(name) {
     alert("Hello "+name);
}

And we can invoke it as

f("Xathrya");

The point is, a function is construct as an expression like constructing any other variable.

Local Variable

A function may have variables, defined by var. In term of scope, they are local variables. We call local because they are only visible inside the function.

function sum(a, b) {
    var sum = a + b;

    return sum;
}

Returning a Value

Like the name, a function should return a value (even though not a must). To return a value, we can use `return` keyword.

function sum(a, b) {
    return a+b;
}

var result = sum(2,5);
alert(result);

If a function does not return anything, it’s result is considered to be a special value, undefined.

Function is a Value

In JavaScript, a function is a regular value.

Just like any value, a function can be assigned, passed as a parameter for another function and so on. It doesn’t matter how it was defined.

function greet(name) {
    alert("Hello "+name);
}

var hello = greet; // assign a function to another variable

hello("dude");     // call the function

The function is assigned by reference. That is, a function is kept somewhere in memory and greet is a reference (or you could say pointer) to it. When we assign it to hi, both variables start to reference the same function.

A function can be used as an argument for another function. In extreme, we can declare a function which act as argument. Here what we talk about:

function runWithOne(f) {  // runs given function with argument 1
    f(1)
}

runWithOne(
    function(a){ alert(a) }
)

Logically, a function is an action. So, passing a function around is transferring an action which can be initiated from another part of the program. This feature is widely used in JavaScript.

In the example above, we create a function without a name, and don’t assign it to any variable. Such functions are called anonymous functions.

Running at Place

It is possible to create and run a function created with Function Expression at once.

(function() {
    var a, b;    // local variables

    // ...       // and the code

})()

Please note the usage of parenthesis and curly-bracket, it matters.

Running in place is mostly used when we want to do the job involving local variables. We don’t want our local variables to become global, so wrap the code into a function.

After the execution, the global namespace is still clean. That’s a good practice.

In the above code, we wrap the function so that interpreter consider it as a part of statement. Hence, the Function Expression. If a unction is obviously an expression, then there’s no need in wrapping it, for instance:

var result = function(a,b) { return a+b }(2,2);
alert(result) // 4

We see that the function is created and called instantly. That’s just like var result = sum(2,2), where sum is replaced by a function expression.

Named Function Expression

A function expression may have a name. The syntax is called named function expression (or NFE).

var f = function greet(name) {
    alert("Hello "+name)
}

As we said, a function is a value. Therefore we can invoke the function name (in this case greet).

NFEs exist to allow recursive calls from anonymous functions.

Function Naming

There is popular convention to name a function. A function is an action, so it’s name should be a verb, like get, read, calculateSum, etc.

Short function names can be allowed if:

  • A function is temporary and used only in nearest code. Same logic as with variables.
  • A function is used everywhere in the code. So from the one hand, there is no danger to forget what it does, and from the other hand, you have less writing.The real-world examples are ‘$’, ‘$$’, ‘$A’, ‘$F’ etc. JavaScript libraries use these names to make frequent calls shorter.

In other cases, the name of a function should be a verb or multiple words starting with a verb.

Object in JavaScript

December 9, 2015 | Article | No Comments

JavaScript has object. We have cover it a bit and compactly, now we will discuss it deeper.

JavaScript object can be view as two different system. One, we can see object as an associative array (aka hash). It stores key-value pairs. On the other side, objects are used for object-oriented programming, using dot notation to access properties and method.

In modern day, JavaScript object also used as a data format known as JSON (Java Script Object Notation). However that is beyond our scope. We will only speak about JavaScript Object, like it is.

Objects, See in Simple Way

Objects in JavaScript, in many ways, are like objects in the real world (world outside programming language). Technically, we model them. In the real world, an object is just a “thing” or noun: a car, a table, a chair, a bottle.

Every objects have:

  • Properties (analogous to adjectives): The car is black.
  • Methods (like verbs in sentence): The car can be started, by turning ignition key.
  • Events: turning the ignition key results in the car starting.

Object-oriented programming (OOP) tries to make programming easier by modelling real-world objects. Let’s say we were creating a car simulator. First, you create a car object, giving it properties like colorand current speed. Then we need to create methods: perhaps a startmethod to start the car, and a brakemethod to slow the car, into which we need to pass information about how hard the brakes should be pressed so that you can determine the slowing effect. Finally, you would want to know when something happens with your car. In OOP, this is called an event. For example, when the gas tank is low, the car sends a notification (that light on the dashboard) letting us know it’s time to fill up. In this code, you would want to listen for such an event so that you can do something about it.

Now, unlike real object-oriented programming language, JavaScript doesn’t dive to deep. We have no interest in complex matter such as inheritance, polymorphism, etc. We just need object in simple way.

Creating Object

An empty object (you may also read as empty associative array) can be created with one of two syntaxes:

o = new Object()
o = { }

The values will be stored as key-value pair. The “properties” can be assigned or delete using “dot notation”. Unlike static type like C++, we can add or delete properties / method dynamically at need.

var obj = { }           // create empty object
obj.name = 'Xathrya';   // add entry with key 'name' and value 'Xathrya'

alert(obj.name);        // get value by key 'name'

delete obj.name;

We can also use brackets instead of dot. The key is passed as a string.

var obj = { }             // create empty object
obj['name'] = 'Xathrya';  // add entry with key 'name' and value 'Xathrya'

alert(obj['name']);       // get value by key 'name'

delete obj['name'];

Both give same result.

We can also declare an object type, like any OOP language. It is actually a group of key-value pairs. The key-value pairs will act as properties and/or method, enclosed by curly-bracket and written as list separated by comma. The key-value pair is written separated by : (colon) operator. For example:

objectLiteral

Which in turn:

var menuSetup = {
    width: 300,
    height: 200,
    title: "Menu"
}

// same as:

var menuSetup = { }
menuSetup.width = 300;
menuSetup.height = 200;
menuSEtup.title = 'Menu';

It is also possible to create nested object:

var user = {
    name: "Xathrya",
    id: 13510,
    birthdate: {
        day: 27,
        month: 9,
        year: 1991
    }
}

alert(user.name);          // "Xathrya"
akert(user.birthdate.day); // 27

Non-Existing Properties

We know that we can fetch property from an object. But if the property does not exist, then undefined is returned. It is the sign for us that the indicated property is undefined, or not exist.

var obj = { }

var value = obj.nonexistant;

alert(value);

So, to check whether the value is defined, we can use following:

if (obj.name !== undefined) {   // strict comparison
    alert("I've got a name!");
}

Checking If a Key Exists

To see if a property is defined in object, we can use “in” operator to check it.

"key" in object         // true if key exist

Iterating Over Keys-Values

Iterating a keys-values pair is like using foreach, iterating each element of an object. JavaScript has made a special syntax for..in to do so. This syntax will list object properties, using a “pointer” to point to a properties one at a time.

for (key in obj) {
    ... obj[key] ... operated
}

Let’s see how we do it:

var menu = {
    width:  300,
    height: 200,
    title: "Menu"
};

for(var key in menu) {
    var val = menu[key];

    alert("Key: "+key+" value:"+val);
}

There, the key will enumerate the key inside object menu. The key would be “width”, “height”, “title”.

In theory, the order of iteration over object properties is not guaranteed. In practice, there is a de-facto standard about it.

Object Variables are References

A variable which is assigned to object actually keeps reference to it. That is, a variable stores kind-of pointer to real data.

We can use the variable to change this data, this will affect all other references.

var user = { name: 'Xathrya' };   // user is reference to the object
var obj = user;                   // obj ans user refer to same object
obj.name = 'Sabertooth';          // change data in the object

alert(user.name);                 // now it is 'Sabertooth'

A major drawback is JavaScript have characteristic like Java. The variable is reference, not a value / pointer. Therefore we cannot modify the value of object directly.

function increment(val) {
    val++;
}

var val = 5;
increment(val);
alert(val);          // val is still 5

Instead, we can still do this, pass the value inside of a container instead of the reference.

var obj = { val: 5 }
function increment(obj) {
    obj.val++;
}

increment(obj)
alert(obj.val);        // obj.val is now 6

The difference is because in first example variable val is changed, while in second example obj is not changed, but data which it references is modified instead.

Properties and Methods

We can store anything in object. Not just a simple value, but also functions. Remember that functions is also key-value pair with value as function.

var car = {
    name: "XathCar",
    model: 500,
    weight: 850,
    color: "white",

    curSpeed: 0,

    start: function() {
         alert("Car is started");
         this.curSpeed = 0;
    }

    drive: function() {
         alert("Car is running");
         this.curSpeed += 10;
    }

    brake: function() {
         alert("A brake is pressed");
         this.curSpeed -= 5;
    }
};

Here we have functions stored by key ‘start’, ‘drive’, and ‘brake’.

Note the this keyword inside the functions. When a function is called from the object, this become a reference to the object.

To call a method, we can use something like this:

car.start();
car.drive();
car.brake();

To check if a method is exists, we can just check it using if syntax:

if (car.start) car.start();

Constructor

Constructing an object can use new function.

The thing which will be an object should be declared as a function. The function then can have some properties and also some methods. Inside the function, we also have this pointer. Instantiation will take a function name and a keyword new before it.

For example:

function Animal(name) {
    this.name = name;
    this.canWalk = true;
    this.canFly = true;
}

var animal = new Animal("PenQueen");

alert(animal.name);

Which has same result as:

var animal = {
    name: "PenQueen",
    canWalk: true,
    canFly: true
}

If the function returns an object, `this` is ignored.

function Animal() {
    this.name = 'Kitty'
    return { name: 'Salamander' }  // <-- will be returned
}

alert( new Animal().name )         // Salamander

Convention speaking: all functions which are meant to create objects with new have uppercased first letter in the name.

If the function don’t take any arguments, we may omit braces.

Built-In Object

The standard library of JavaScript includes a list of built-in objects. They are, for example:

  • Math – provides methods for mathematical computations,
  • Date – for dates,
  • RegExp – for regular expressions.

Function are also objects, instances of the new Function.

For browser, there are also global object / variable such as:

  • Document
  • Window

Compact Tutorial on JavaScript Basic

December 9, 2015 | Article | 1 Comment

We will not cover how to program in JavaScript in detail but rather what to do in JavaScript.

Where to Write?

There are some alternatives to write a piece of JavaScript code: inside a document using <script>, inline on HTML tag, external files.

JavaScript can be written on enclosing pair of tag <script> </script>

<script>
alert("My First JavaScript");
</script>

We can write this on any section of HTML document, for example: <body>, <head>, or both. It is a common practice to put code in the <head> section, or at the bottom of the page. This way they are all in one place and do not interfere with page content.

For example, this code is a script embedded to <body> section.

<!DOCTYPE html>
<html>
<body>

<h1>My Web Page</h1>

<p id="demo">A Paragraph</p>

<button type="button" onclick="myFunction()">Try it</button>

<script>
function myFunction()
{
document.getElementById("demo").innerHTML="My First JavaScript Function";
}
</script>

</body>
</html>

JavaScript can be embedded to a HTML tag. For a simple code this approach can be used. Here we modified the above code:

<!DOCTYPE html>
<html>
<body>

<h1>My Web Page</h1>

<p id="demo">A Paragraph</p>

<button type="button" onclick="document.getElementById('demo').innerHTML='My First JavaScript Function'">Try it</button>

</body>
</html>

Last, we can write a JavaScript code in external files and make the HTML file loads them. This way, several web pages can use it. External JavaScript files have the file extension .js.

To include external script, point to the .js file in the “src” attribute of the <script> tag:

<!DOCTYPE html>
<html>
<body>
<script src="myScript.js"></script>
</body>
</html>

Dynamic Type Inference

JavaScript is a scripting language. It is a language which dynamically infer the types of objects, instead of forcing object definition.

For example, in C or C++ you can have a variable which is defined as integer, floating point number, a character, etc. Including user-defined type. When declaring a variable, you have to specify what kind of variable (the type) of it. When you fail to define it, compiler will refuse to process. You should also make sure the type is defined / declared ahead of variable declaration. Here is the example in C++:

int myInt = 9;
float myFloat = 3.14;
char myChar = 'X';

In JavaScript, no such things exists. Instead you can have all defined as a variable, regarding the value.

var myInt = 9;
var myFloat = 3.14;
var myChar = 'x';

Not only primitive type, you can treat object with same manner.

You can also write all variable declaration in one line, separated by comma:

var lastname="Sabertooth", age="21", job="CEO";

or you can span it to multiple lines, but still the declaration is separated by comma:

var lastname="Sabertooth",
age="21",
job="CEO";

Though indentation is not really a matter, it is advised to watch your indentation.

As implication of this behavior, you can assign any value to JavaScript variable. But, in computer programs variable are often declared without no value. The value can be something that will be provided later, like user input. However how we declared an empty variable? Here undefined comes.

The variable carname will have the value undefined after the execution of the following statement:

var carname;

An undefined value is not instance of any type. It is purely declaring the variable as empty.

There is also exists the sibling, null value.

A Statement, Code Blocks

A statements are “commands” to the browsers or interpreters.

A statement can be an expression or simply a function / procedure invocation.Like it’s predecessor, JavaScript can use semicolon ; to separates JavaScript statements. This enables us to write multiple statement on a line. However, write semicolon at the end is optional.

document.write("Xathrya Sabertooth"); document.write(" was here");

The statements are case sensitive. Watch capitalization closely. A function getElementById is not same as getElementByID. A variable named myVariable is not same as MyVariable.Some statements can also be grouped together in blocks. Blocks started with a left curly bracket, and ended with a right curly bracket. Blocks are used for defining function, branching (if-else, switch), repetition (for, do, while), or simply grouping statements.Different in Way of Code

JavaScript also use different paradigm. It is still executed in sequential, means a higher line of code will be executed earlier than code in bottom.

What we means in different paradigm?

Writing JavaScript require ones to know event-driven model. Lot of code or function are act as callback. They are executed when some kind of event has been triggered. The event can vary, such as button click, page load, etc. The event can be associated to specific page element such as button, image, etc.

If you have code in native programming language, for example C/C++, you can feel the difference. In C/C++ you have a main function where all execution alive. In JavaScript, they are persistent and wait for a call. This should be noted!

We Talk About Input/Output

In JavaScript, we can say manipulating I/O is the primary goal. We say input when we grab content of some elements, whether we process it or not. We say output when we write things to document, whether it is processed or not. The output / writing can be create, update, or delete DOM. Remember that JavaScript can manipulate a DOM freely.

I/O can also be considered as communication with other entity, such as remote server in AJAX.

What are Types?

In fact, JavaScript do have types declared. They are strings, number, boolean, and object.

A string is a series of characters. It can be any text inside quotes (single or double quotes). You can also use quotes inside a stirng, as long as they don’t match the start quote.

var carname="Volvo XC60";
var carname='Volvo XC60';
var answer="It's alright";
var answer="He is called 'Johnny'";
var answer='He is called "Johnny"';

A number is a generalization of integer and floating point number. JavaScript also support large number using scientific notation.

var x1=34.00;      // Written with decimals
var x2=34;         // Written without decimals
var y=123e5;      // 12300000
var z=123e-5;     // 0.00123

A boolean is a special type which has only two kind of values: true or false. It is often used in condition testing. We will

var x=true;
var y=false;

JavaScript object is delimited by curly braces. Inside the braces the object’s properties are defined as name and value pairs. The properties are separated by commas. Here is how we write a JavaScript object. Note that we can use one line to define all, or single line to define each.

var person={
firstname : "Xathrya", lastname  : "Sabertooth",
id        :  5566,
company   : "Sakraysoft Nanotech"
};

When we declare an object, we will use following syntax:

var Xathrya = new person;

and addressing the properties by two ways:

name = Xathrya.lastname;
name = Xathrya["lastname"];

You can also create a new object for String, Number, and Boolean respectively.

There is also a type which is defined as a collection of value. This type is called as Array(). Like we predict, JavaScript array is unlike C/C++ array. JavaScript can be any value.

var X = new Array();
X[0] = "Xathrya";
X[1] = "Sabertooth";
X[2] = 13510030;

Operators

Assign

Assign is an operator to assign value to a variable. In other world, it write a value to variable. The operator is =

y = 5;
z = 2;
x = y + z;

The x will be 7.

JavaScript can support C-like assignment operators, using itself as first operand and modify the value with second operand. The operators we talk about are: += (add this with), -= (subtract this with), *= (multiply this with), /= (divide this with), %= (mod this with).

For example:

var X = 10;
X += 2;    // X now 12
X -= 3;    // X now 9
X *= 4;    // X now 36
X /= 3;    // X now 12
X %= 8;    // X now 4

Arithmetic

There are various arithmetic operations supported by JavaScript: + (addition), – (subtraction) , * (multiplication), / (division), % (modulus or division remainder), ++ (increment), — (decrement).

var x = 15;
var y;

y = x + 3;   // y now 15 + 3 = 18
y = x - 4;   // y now 15 - 4 = 11
y = x * 2;   // y now 15 * 2 = 30
y = x / 3;   // y now 15 / 3 = 5
y = x % 9;   // y now 15 % 9 = 6

Overall, the operators are similar to C and derived programming language’s operators.

Comparison

Comparison operators are operators used for comparing value of variable. There are three “state” available in Math: less, equal, greater. From this three states, we can have some comparison: < (less than), <= (less than or equal), == (equal), != (not equal), > (greater than), >= (greater than or equal). JavaScript also expand operators, adding two new operator: === (exactly equal to), !== (not equal). All operator will return a boolean value, true or false.

So what is the difference of == to === and != to !===?

Remember that JavaScript is resolve type dynamically. The === means both variable have equal value and equal type. While the !== means the variable has different value or different type.

Here is the example:

var x = 5;

x == 8;      // false
x == 5;      // true

x === "5";   // false
x === 5;     // true

x != 8;      // true

x !== "5";   // true
x !== 5;     // false

x > 8;       // false

x < 8;       // true

x >= 8;      // false

x <= 5;      // true

This operator can be used to evaluate a condition.

String operation

Operator + can also be used to string. It will concatenate two string and produce new string.

txt1 = "Xathrya ";
txt2 = "Sabertooth";
txt3 = txt1 + txt2;    // txt3 = "Xathrya Sabertooth"

When you adding two number, a new summed value will be returned. However, when you “add” string and a number, it will produce a string:

x = 5 + 5;         // x = 10
y = "5" + 5;       // y = "55"
z = "Hello" + 5;   // z = "Hello5"

Logical

These operators act as conjunction to one or more logical expression and then return a boolean value. These operators consists of: && (and), || (or), ! (not).

An && “and” operator need two operand and return true when both expression has value True. In math, it is denoted as ^.

An || “or” operator need two operand and return true unless both expression has value False. In math, it is denoted as v.

A ! not operator need one operand and invert the value. For example if the expression is False, it will produce True. Otherwise, it will product False. In math, it is denoted as ~.

Here we have a complete list:

truthtable

Social media & sharing icons powered by UltimatelySocial