We're hiring!

We're actively seeking developers for our new Detroit location. Learn more

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 techinique 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.
 

This entry was posted in Languages and tagged . Bookmark the permalink. Trackbacks are closed, but you can post a comment.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>