One question I'm fond of asking in interviews is how to create a set of
strings to which values may be added in an efficient manner. Furthermore,
membership checks must be reliable and as fast as possible. This post can
be considered the model answer. ;)
A decorator is a function which takes a function and returns a function:
decorator = (fn) ->fn
Obviously, this doesn't do anything useful. It's the fact that a decorator
can return a function which behaves similarly to the function passed to it
that makes the pattern interesting. Commonly a decorator will simply wrap a
function invocation in a check of some sort:
Decorators are commonly used in Python — which provides special syntax for
"decorating" functions — but are rarely seen in JavaScript code. This despite
the fact that JavaScript's first-class functions are ideally suited to the
task. Perhaps CoffeeScript's lighter-weight function syntax will result in
decorators making more frequent appearances in JavaScript code.
I recently came across an interesting article at wonko.com on
HTML escaping, which provoked me to rewrite Bitbucket's escape
function (invoked from within Underscore templates):
This ensures that inserted content cannot escape the confines of a quoted
attribute value. Unquoted attributes are more problematic:
Unquoted attribute values are one of the single biggest XSS vectors there
is. If you don’t quote your attribute values, you’re essentially leaving the
door wide open for naughty people to inject naughty things into your HTML.
Very few escaper implementations cover all the edge cases necessary to
prevent unquoted attribute values from becoming XSS vectors.
To accommodate unquoted attribute values, the following function could be
used instead:
I created a jsPerf test case which confirms that there's a performance
hit associated with using this more liberal regular expression. Keep in mind,
though, that if “A” takes 1ms to execute and “B” takes ten times as long,
“B” still only takes 10ms. Quite often a significant comparative speed
difference is insignificant in absolute terms; I'd argue that this is the
case here.
Recording of Yehuda Katz's presentation from Bay Area jQuery Conf 2011.
While watching this it finally became clear to me why storing state in
the DOM is a terrible idea for complex applications. The approach comes
unstuck as soon as one wishes to display an entity more than once in a
view (such as in a list–details split view).
JavaScript's regular expressions are less than awesome, sadly. One
limitation is the lack of start of string and end of string anchors.
In Perl, for example, \A matches the start of a string, \Z the end.
Most of the time it's possible to get by with ^ and $ which act like
\A and \Zexcept in multiline mode where they match the start and
end of any line.
It's possible, though, to have a lookahead act as an end of string anchor
in multiline mode:
It'd be nice to be able to write text.contains('✈'), which is both intuitive
and self-documenting. The language does provide a way to make such expressions
terser, but it's far from obvious.
// bitwise NOTif(~text.indexOf('✈'))
Bitwise operators make my head spin, but the Perl programmer in me thinks
they're awesome. I don't profess to understand why exactly the bitwise NOT
operator does what it does, but I've played with it enough to know how it
behaves. It's equivalent to the following function, at least for the values
that can be returned by indexOf.
functionbitwiseNot(n){return-n-1;}
indexOf returns -1, 0, 1, 2, 3, or some other positive integer. When these
values are used as operands for the bitwise NOT operator, the results are 0,
-1, -2, -3, -4, and so on. Therefore, ~text.indexOf('✈') is equivalent to
text.contains('✈') in Boolean contexts.
It's unacceptable for any website or web application to output dates and
times using an arbitrary time zone. Displaying dates and times in UTC/GMT
is only slightly better: dates cannot be relied upon, and users must perform
mental gymnastics in order to localize date–time combos.
When dealing with dates, it's not uncommon to need to convert an integer
into an ordinal number (1st, 2nd, 3rd, etc.). While making improvements to
Mango recently I wrote a function to do this, first in Python, later in
JavaScript.
By special-casing 11, 12, and 13, the function becomes incredibly simple.
I'm pleased to have found a context in which JavaScript's switch statement
is almost elegant. The problem, usually, is the need to break to prevent
fall-through. When used within a function, though, the return statement is
able to perform this role, making the JavaScript code almost as readable as
the Python equivalent.
Recently I listened to Gary Bernhardt comparing Python and Ruby. In
the talk Gary states that he finds Ruby code ugly and Python code beautiful.
He then goes on to say that the things which reduce Ruby's aesthetic appeal
are the very things which allow Ruby to do beautiful things impossible in
Python.
Gary provides several examples of equivalent code in Python and Ruby to
highlight situations in which one language reads better than the other, such
as the following.
The Ruby code (the one beginning with ids.map) reads top to bottom and is
easy to follow. The Python code is equally succinct but takes a bit of effort
to decipher.
I've been greatly enjoying the act of writing JavaScript lately, so simply for
pleasure I worked out the JavaScript equivalent.
filter, though, just removes from an array the items which fail
the provided "test". So the code above is on the right track, but fails
to produce a list of names.
reduce is the correct method for the job. reduce "reduces" an
array to a single value, which could be a string, an object, another
array — whatever!
Note the empty array ([]) on line 5 – that's our "accumulator".
So you have some number, x, which you want to round to the nearest integer.
Easy, right?
x=Math.round(x);
Sure, but is this the fastest option? I think not.
x=x<0?x-0.5>>0:x+0.5>>0;
What the heck's going on here? >> is JavaScript's right shift operator.
It shifts a number's binary representation n bits to the right, where n
is the value to the right of the operator. Since n is 0 in this case, no
shifting will occur, although the resulting value will be an integer.
Note that this approach results in -82.5 being rounded to -83.
If, for some reason, your code calls Math.round() millions of times, it may
be worth investigating the bitwise approach to avoid the overhead of all those
function calls.
Stick to Math.round() the rest of the time, though, as it makes for much
clearer code. Never optimize prematurely.
Earlier I wrote some code which repeatedly calls a function which performs
a database query – often the same query. This encouraged me to explore
various ways to cache the results of function calls in both Python (to solve
my immediate problem) and JavaScript (because I find that language endlessly
fascinating).
I played around with Fibonacci, which is a well suited to the task: it
can be described in just a couple of lines of code yet benefits enormously
from caching due to its recursive nature.
I write a lot of Python. I also write a lot of JavaScript. As I switch between
the two (often several times in a day) I sometimes find myself trying to do
something in one using the syntax of the other. The most common example is
joining a list.
Python:
' '.join(['foo','bar'])
JavaScript:
['foo','bar'].join(' ')
Often — as is the case above — the syntactical differences are minor, but
there are times when there's no direct translation.
MooTools, for example, adds the every method to the Array object.
This makes it possible to write some rather terse conditional statements.
varnumbers=[87,33,21,75];if(numbers.every(function(n){returnn%3==0;})){window.alert('The numbers are all divisible by 3.');}
Python lists have no comparable method, so how would one write this in Python?
numbers=[87,33,21,75]if[nforninnumbersifn%3==0]==numbers:print'The numbers are all divisible by 3.'
This approach involves using a list comprehension to create a list of numbers
which are divisible by 3, and comparing this list to numbers. If the lists
are equal, everything in numbers is divisible by 3.
This is reasonably succinct, but not terribly efficient since each document is
checked for every search term. Given that we're not interested in documents
that lack even a single search term, it should be possible to rewrite this code
so that we don't waste time on lost causes.
It turns out that Python has just the thing for the job: in Python, a loop
statements may have an else clause!
terms=['python','list','methods']matches=[]fordocumentindocuments:forterminterms:ifdocument.body.find(term)==-1:breakelse:# every term was foundmatches.append(document)
Loop statements may have an else clause; it is executed when the
loop terminates through exhaustion of the list (with for) or when
the condition becomes false (with while), but not when the loop is
terminated by a break statement.
I'm looking forward to finding more good spots to make use of else
clauses with my Python loops. :D
Over the past few months I've reached a startling realization: JavaScript is
a tremendously capable language.
The reason that it took me so long to discover this is that the playing field
has never been fair. On the one hand I've been writing application code for
the server, a stable, predictable environment. On the other hand I've been
adding interactivity on the client's side, dealing with inconsistencies on
multiple fronts, not least of which is the DOM API.
Comparing Python and JavaScript, for example, by using the former to quickly
put together a website using the excellent Django framework while using the
latter to add drag and drop functionality is to compare apples and oranges.
Actually, it's more like comparing apples to root canals.
I've spent the afternoon creating a custom scrollbar for a products viewer
which utilizes CSS transitions, reflections, and other goodness.
Simple arithmetic dictates how long to make the scrollbar and where to position
it, but I could not get my theoretical calculations to play out in the browser.
It turns out that I'd been calling the wrong MooTools method. I'd been doing…
element.setStyle('left',offset);
rather than…
element.setPosition({x:offset});
Frustratingly, setStyle('left', offset)appeared to work, but its behaviour
was unpredictable. I'm still confused by this, but at least I'm no longer
stuck.
Comment forms that don't provide previews — or at least an indication of
how comments are processed — really annoy me. If I decide to leave a comment
I take care to avoid spelling mistakes and grammatical errors. It's quite
upsetting, then, to see my code snippet completely mangled and my carefully
typed links displayed in plain text (<a href="…).
Despite my appreciation of the preview, not one of my sites provided this
service until a few hours ago. Now that I've migrated from WordPress to
Mango I'm able to spend some time working on front-end code. My first two
challenges were localizing dates and times, and integrating wmd.
Getting wmd working turned out to be extremely easy, but I was not content with
a live preview of the comment only. No, I wanted the preview to resemble as
closely as possible the published result, which meant updating the preview area
in response to changes to "name", "e-mail", and "website" as well as to changes
to the comment itself.
Early this year I wrote a post titled
Auto-populating input fields with Prototype. Looking at the code now,
I realize that it's not very pretty. I'm rewriting this site's JavaScript
in MooTools, and the new code is quite a bit more elegant.
// provide input hintswindow.addEvent('domready',function(){$$('input[placeholder]').addEvents({focus:function(){if(this.hasClass('placeholder')){this.removeClass('placeholder').set('value','');}},blur:function(){if(this.get('value')===''){this.addClass('placeholder').set('value',this.get('placeholder'));}}}).fireEvent('blur');});
I really appreciate the fact that MooTools provides addEvents in addition
to addEvent. As a result, the code above is clearer than a well-written
Prototype equivalent.
Regular expressions are powerful, useful, and — in my opinion — lots of fun!
Thanks to the prevalence of Twitter, every web developer will be exposed to
regex sooner or later: before outputting tweets in HTML, Twitter names and
hyperlinks must be wrapped in anchor tags.
Matching @names
Here's the gist: a match will begin with "@" and the at sign must be followed
by one or more word (letter / number / underscore) characters. The @name must
either appear at the beginning of the tweet or be preceded by a space. This
prevents the regular expression from matching "@example" in "me@example.com".
[…] Moments ago I used JSLint for the first time; I plan to use it frequently
from this point forward. I have one question, though, concerning the acceptability of
extra commas. Consider the following code snippet:
var ninja = {
name: 'Hattori Hanzou Masashige',
shuriken: 5,
attack: function () {
if (ninja.shuriken) {
ninja.shuriken -= 1;
window.alert('Hai-Ya!');
}
},
};
JSLint returns an extra comma error for the unnecessary comma preceding the closing
brace. I would argue, though, that this in not an error. As far as I'm aware, this
comma will not cause problems.
In fact, quite the opposite is true. If one were to insert an additional property or
method after attack one would not need to remember to first add a comma. In Django
it's considered best practice to include a comma after every item (including the last)
in a one item per line collection for this very reason.
I thought I'd give you my two cents, anyway. :)
Regards,
David Chambers
On ,
Douglas Crockford wrote:
Your awareness is incorrect. Have you tested on IE6?
Generally speaking browsers rerender elements as required – in response to DOM
changes effected via JavaScript, for instance. There are times, though, when
the browser (Internet Explorer, I'm looking at you!) needs a gentle nudge.
The post's first comment includes an alternative approach:
element.className=element.className;
I gather that there are situations in which this simple solution fails — it's
no silver bullet — but it fixed a problem I encountered in IE8 earlier this
evening so I'm pleased to have discovered it!
A reasonably common task is to determine whether a particular statement
evaluates as true for every item in a collection. Take list,
for example, an Array containing several numbers:
varlist=[4,-1,3,2,5];
One might wish to determine whether all the numbers in list are
positive. The required logic is as follows:
assume that all the numbers in list are positive, then…
loop through list until the assumption is proven to be false,
or until all items in list have been tested
In plain JavaScript, this can be achieved using a for loop…
Seriously, though, who is writing vanilla JavaScript in 2010? Everyone
and their grandmothers are using JavaScript frameworks these days, and there
are plenty of good ones out there. I recently made the switch to MooTools
from Prototype, after deciding that while jQuery is fantastic, the
MooTools philosophy is more to my liking.
While this gets the job done, it's suboptimal for two reasons: the positiveness
of every item is evaluated, which will often not be necessary; and, well,
it ain't pretty. ;)
Enter every
As is so often the case in programming, if something seems fiddly and difficult
there's probably a better tool for the job. In this case the Array object's
every method is the perfect tool for the job.
I've recently become interested in optimizing sites for the iPhone and iPod
touch. While nothing beats testing on the device itself, I often find it
quicker to test changes on my Mac. Changing the user agent string is a piece
of cake in Safari (Develop > User Agent > Mobile Safari) but what about
adjusting the browser window's dimensions to match those of the iPhone?
I've created two bookmarklets to allow the current page to be loaded in an
iPhone-sized window with a single click:
Many of those who write JavaScript do not come from programming backgrounds
(while I've written plenty of PHP, Python, and JavaScript, I don't have much
experience with "real" programming languages*). As a result, a
significant portion of JavaScript coders do not think of variables as pointers
to memory addresses. This leads to confusion in cases such as this:
varfruits=['orange','lime'];varcolours=fruits;// naïve attempt to duplicate arraycolours.push('yellow');
One might be surprised to learn that fruits now contains not just "orange"
and "lime" but also "yellow". Oops! Here's how it went wrong:
varfruits=['orange','lime'];// fruits points to array containing "orange" and "lime"varcolours=fruits;// colours now points to that same array!
How, then, does one create a copy of the original array? Slice!
Yesterday I wrote a simple class which auto-populates input fields, and
thought it worth sharing. I was originally inspired to write this code
by Roger Johansson's post titled Autopopulating text input fields with
JavaScript. While I approached the problem from a slightly different
angle, I made sure to avoid the pitfalls Roger mentions.
Nothing new here. I've combined Prototype 1.6.1 and the various
files that make up script.aculo.us 1.8.3 (except unittest.js) into one
file, which I've minified using the YUI Compressor. Further compression
has been achieved by gzipping the minified file. All three versions are
available for download:
This prevents caching issues that might otherwise arise upon updating to a
newer version of prototype+scriptaculous (I'll update the three files — and
this post — each time a new version of Prototype is released).
I began this post three months ago, got stuck, and put it in the too hard
basket. I wanted to devise a workable solution to my stumbling block before
publishing this information. I'm getting ahead of myself, though. First, the
background.
As I began writing this post, I had just completed a redesign of this site.
The new design removed unnecessary distractions to allow readers to focus on
the clearly presented content. I moved site navigation from the sidebar (which
I axed altogether) to the header. I decided to fix the header in place so that
the navigation and search form would always be visible. This required very
little effort, but overcoming the problem posed by fixed-position headers
took a great deal of trial and error. To save others from going through this
tortuous process I'll describe my various approaches, and list the benefits
and drawbacks of each.
In my post titled Captions over images I advocate the use of definition
lists for captioning images. Earlier today I was asked whether this meaningful
markup could be used in conjunction with an "image slider" such as
Easy Slider 1.5.
I had a look at the Easy Slider source code and decided to write my own image
slider using Prototype rather than hacking someone else's code to pieces. It's
a proof of concept rather than a full-blown "plugin", but it demonstrates that
such functionality is achievable using elegant, meaningful markup.
This is my response to Chris Coyier's screencast titled jQuery Part 3 – Image
Title Plugin which I watched a couple of days ago. Something didn't sit
right with me at the time, and I've now worked out what it was: JavaScript
is not required!
I'll present a JavaScript-free approach for displaying captions over images
that uses truly meaningful markup.
It's no secret – I love Coda! It's a pleasure to use. It looks so damn
good. When I started using SyntaxHighlighter I set out to create a Coda
theme. Thankfully, the good folks at Panic had done the ground work for me.
All I had to do was create a style sheet that would make my code snippets look
as sexy online as they do in my text editor.
This is a JavaScript function for Photoshop which saves the active document
as a 24-bit PNG file. It is equivalent to manually selecting File > Save for
Web & Devices… which means that the file size of the resulting PNG will be
smaller than would be the case using PNGSaveOptions().
Photoshop on Mac limits the length of a File object's file name to
31 characters. Credit for the rename workaround should go to Mark Walsh
who posted the solution on the Adobe forums in a thread titled
Save for web filename problems.
JavaScript does not have associative arrays. (This will be old news
to many.)
Confusion arises from the fact that array syntax in JavaScript is very
similar to array syntax in PHP, a language that does have associative
arrays. Additionally, any object in JavaScript can be treated as an
associative array. This means that if one creates a JavaScript Array
object and proceeds to use PHP's associative array syntax in an attempt
to add items to it, one will succeed in assigning it attribute–value
pairs. The object in question need not be an Array for this to work,
though, so for the sake of clarity using a vanilla Object is advisable.
SyntaxHighlighter is a fully functional self-contained code syntax
highlighter developed in JavaScript (as stated on its wiki). One of its
deficiencies is that it retrieves all its brushes each time a page is
loaded, despite the fact that in many cases only one or two (or none)
are required.
Currently, Prototype is my JavaScript framework of choice (although
I'm really looking forward to trying jQuery). I have used Prototype to
create a brush loader for SyntaxHighlighter, which retrieves brushes on
demand to reduce page loading times (in certain circumstances).
Alex Gorbatchev's SyntaxHighlighter is a well-written bundle which
enables syntax highlighting of code via JavaScript. More than twenty
languages are supported "out of the box", and brushes (JavaScript files
containing language-specific regular expressions) can be created to
support additional languages.
Unfortunately, however, several of the brushes that come bundled with
SyntaxHighlighter are far from perfect. Have a look at the bundled PHP
brush in action below.
I've been using Alex Gorbatchev's SyntaxHighlighter to syntactically
display code of various languages for several months now. When I decided
to post an AppleScript snippet, however, I realised that I was out of luck.
SyntaxHighlighter does not include an AppleScript "brush", and a quick flick
through the SyntaxHighlighter forums did not bring me any joy.
How hard could it be to write a brush for AppleScript?, I wondered. The
handy guide to developing a custom brush got me started, and I was soon
busy trying to encapsulate AppleScript's syntax — along with its keywords and
countless words and phrases with special meanings — into a handful of regular
expressions.