We're hiring!

We're actively seeking developers and designers for our Detroit & Ann Arbor locations.

Properties Behaving like Functions in JavaScript

My pair and I were looking into Chai, a BDD / TDD assertion library for JavaScript, and noticed a very interesting syntax. In many places, where a method took no arguments, Chai removed the need for parentheses.

For example, to verify a listener has been called looks like this:

listener.should.have.been.calledOnce

Or testing that something is truthy:

expect('everthing').to.be.ok;
expect(1).to.be.ok;
expect(false).to.not.be.ok;
expect(undefined).to.not.be.ok;
expect(null).to.not.be.ok;

At first we weren’t sure how this was done. JavaScript requires parentheses (or so we thought) to invoke a function. Leaving the parentheses off should return the property.

Looking into the source, we found that Chai was using the defineProperty method in JavaScript to create a property that acted like a function.

If you’re unfamiliar with the defineProperty call, try Understanding “Prototypes” in JavaScript by Yehuda Katz.

Overall this technique is very useful for Chai. It helps their API read clearly, which could help a test suite function as documentation. However there could also be confusion when accessing what you think is a property, which could have unintended consequences. This pattern should be used with great care.
 

Dustin Tinney (36 Posts)

This entry was posted in Web Apps and tagged . Bookmark the permalink. Both comments and trackbacks are currently closed.