object

Inherited Accessor Property Can Only Be Overridden by Accessor Property

In Javascript, define a property prop as an accessor property via getter/setter:

1
2
3
4
var obj = {
get prop() {},
set prop() {}
};

And the property will have the following attributes:

> Object.keys(obj)
[ 'prop' ]
> Object.getOwnPropertyDescriptor(obj, 'prop')
{ get: [Function: prop],
  set: [Function: prop],
  enumerable: true,
  configurable: true }

Now, create a new object that inherits obj, and attempt to overwrite the accessor property by a data property:

1
2
var foo = Object.create(obj);
foo.prop = 'data';

But, the same property of the new object cannot be created:

> Object.keys(foo)
[]
> Object.getOwnPropertyDescriptor(foo, 'prop')
undefined

That is because that the property is an accessor property and it cannot be overridden by a data property. It can only be overridden by an accessor property:

1
2
3
4
5
6
Object.defineProperty(foo, 'prop', {
get: function prop() {},
set: function prop() {},
enumerable: true,
configurable: true,
});

Then, the foo object will have its own property named prop:

> Object.keys(foo)
[ 'prop' ]
> Object.getOwnPropertyDescriptor(foo, 'prop')
{ get: [Function: prop],
  set: [Function: prop],
  enumerable: true,
  configurable: true }

Avoid Assigning undefined to an Object Property

A property value should be any JavaScript value except for undefined. If you do something like this (albeit it is legal):

1
var foo = { bar: undefined };

will leads to confusing code. Because when accessing the property value:

1
console.log(foo.bar); // undefined

It will returns undefined. But you are not sure if it means the property exists or not or the value of the property is set to undefined. Therefore, you should do:

1
var foo = { bar: null };

This indicates that the property is expected, and with the value of null.

You do be able to check the existence of a property by:

1
2
Object.keys(foo); // ['bar']
foo.hasOwnProperty('bar'); // true

But more importantly, if you serialize the object with JSON.stringify, properties with undefined will be omitted:

1
JSON.stringify({ bar: undefined }); // '{}'

According to JSON specification, a value can be a string in double quotes, or a number, or true or false or null, or an object or an array. undefined is not a valid JSON value.

null is fine:

1
JSON.stringify({ bar: null }); // '{"bar":null}'

So, for the best practice, avoid assigning undefined to a property of an object. Use null to indicate the expected property without a value. This will increase portability when using JSON to serialize.

CoffeeScript Array of Objects

We frequently find ourselves need to define array of objects. In CoffeeScript we can write in the following way:

1
2
3
4
5
6
7
8
9
10
arr = [
{
name: 'foo'
pass: 'oof'
}
{
name: 'bar'
pass: 'rab'
}
]

Or another format is to insert a comma:

1
2
3
4
5
6
7
arr = [
name: 'foo'
pass: 'oof'
,
name: 'bar'
pass: 'rab'
]

In the spirit of CoffeeScript, we want to avoid using braces as much as possible. Therefore, the second method is preferred.