Wednesday, September 23, 2015

JavaScript's new operator

In a previous post we explored the class-ical programming paradigm in JavaScript
The constructor pattern is a fundamental aspect of the class-ical paradigm
A constructor is code using which objects can be created from a class using the 'new' keyword
.
Under the hood, JavaScript uses it's prototypal mechanism to support this feature. In other posts I explore the prototypal form in depth. For now, lets try to understand how 'new' works:

Lets create a function Person to behave like a Java Class

1
2
3
4
5
function Person(first, last) {
  this.first = first;
  this.last = last;  
}
var s = new Person("Deepak", "Anand");

Here are the things that happened after the last line was executed:

  1. new creates a new object, lets call it this
  2. the (constructor) function Person is called like so: this.Person ("Deepak", "Anand")
  3. this is returned
Using upper-case for function-names that are used as constructors is convention only, not a language construct.

Now, what if you want methods in your "class"

Easy enough....

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function Person(first, last) {
  this.first = first;
  this.last = last;
  this.getFullName = function() {
    return this.first + ' ' + this.last;
  };
  this.getFullNameReversed = function() {
  return this.last + ', ' + this.first;
  };
}

This works, but is not very efficient. For every Person instance, 2 function objects are created.
The solution is to add methods to the function's prototype property like so:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function Person(first, last) {
  this.first = first;
  this.last = last;
}
Person.prototype.getFullName = function() {
  return this.first + ' ' + this.last;
};
Person.prototype.getFullNameReversed = function() {
  return this.last + ', ' + this.first;
};

References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript

Tuesday, September 1, 2015

Web Components - API dilemma

Some time ago, I started looking at Web Components. It sounded promising at a high level.

But as it often is, the devil is in the details.

As I started playing with it, I realized that the APIs of HTML Elements have 2 surface areas
1. Attributes
2. Properties

Quick refresher on what these two are:
Attributes are available on the HTML elements, you use them via the following APIs
getAttribute(attr-name)
setAttribute(attr-name, attr-value)
removeAttribute(attr-name)
hasAttribute(attr-name)
Eg: if it were a <input type= "text" value="foo"> element
one of its important attributes is "value"

Properties are available on the DOM object. you can access them like so:
element.propertyName
i.e. for the input element example, it would be
element.value

For reasons I dont quite understand, with the HTML Form elements,  the behavior of attributes and properties is not consistent. Its a topic of another post. Please read it before continuing if that does not sound familiar to you.

My puzzle is
Should a web component behave similar to the native HTML form elements or should it
allow users to use both attributes and properties to get and set its state.

It was great to find a best practices document on the web components community
Link to Web Component best practices

Items 4 and 10 are of interest. To quote:
4.  Attributes for data in: Use attributes to pass configuration in.
10. Harmonize your declarative and imperative APIs: Attributes form (part of) your declarative API; your prototype defines your imperative API. Try to keep the analogous parts linked whenever possible so a user can modify either with the same effect

# 4 seems reasonable, a different way of saying the first part of #10 "Attributes form (part of) your declarative API"
The second part of #10 is both a reasonable and an inconsistent recommendation
" Try to keep the analogous parts linked whenever possible so a user can modify either with the same effect"
It is inconsistent because the HTML form elements do not behave as described. Attributes are specified for the component initial configuration whereas properties are used to get/set them after they are constructed. So, attributes are not in sync with the properties. This is something that web developers have come to accept and do not expect to use the attributes for programmatic get/set to the component post-construction.
So, this point is not a best practice, on the contrary, a violation of the standard HTML element behavior, from an HTMl purist perspective.
But all that said, if you are developing web components, choose one approach that suits your team best.

Heres an update on the current state of Web Components
http://www.2ality.com/2015/08/web-component-status.html