Because @Robert K and @mattcasey both have good code, I thought I'd contribute here with a CoffeeScript version, in case anyone in the future could use it:
    String::unescape = (strict = false) ->
      ###
      # Take escaped text, and return the unescaped version
      #
      # @param string str | String to be used
      # @param bool strict | Stict mode will remove all HTML
      #
      # Test it here:
      # https://jsfiddle.net/tigerhawkvok/t9pn1dn5/
      #
      # Code: https://gist.github.com/tigerhawkvok/285b8631ed6ebef4446d
      ###
      # Create a dummy element
      element = document.createElement("div")
      decodeHTMLEntities = (str) ->
        if str? and typeof str is "string"
          unless strict is true
            # escape HTML tags
            str = escape(str).replace(/%26/g,'&').replace(/%23/g,'#').replace(/%3B/g,';')
          else
            str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '')
            str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '')
          element.innerHTML = str
          if element.innerText
            # Do we support innerText?
            str = element.innerText
            element.innerText = ""
          else
            # Firefox
            str = element.textContent
            element.textContent = ""
        unescape(str)
      # Remove encoded or double-encoded tags
      fixHtmlEncodings = (string) ->
        string = string.replace(/\&#/mg, '&#') # The rest, for double-encodings
        string = string.replace(/\"/mg, '"')
        string = string.replace(/\"e;/mg, '"')
        string = string.replace(/\_/mg, '_')
        string = string.replace(/\'/mg, "'")
        string = string.replace(/\"/mg, '"')
        string = string.replace(/\>/mg, '>')
        string = string.replace(/\</mg, '<')
        string
      # Run it
      tmp = fixHtmlEncodings(this)
      decodeHTMLEntities(tmp)
See https://jsfiddle.net/tigerhawkvok/t9pn1dn5/7/ or https://gist.github.com/tigerhawkvok/285b8631ed6ebef4446d (includes compiled JS, and is probably updated compared to this answer)