-1

Why doesn't this work?

decodeURI('\n') => newline;
decodeURI("\\n") => '\n', thus presumably...
decodeURI(decodeURI("\\n")) // => gives '\n' instead of newline

But this does?

JSON.parse('"\\n"') // => newline

Point here is to be able to build a \* character string, then convert it to its actual character via decodeURI.

I'd like to avoid using JSON.parse if possible.

EDIT

I realize the way I approached this was confusing. A better question would have been to ask how decodeURI and JSON.parse do their conversion from the string literal to the resolved character and if there was something more direct.

Community
  • 1
  • 1
Karric
  • 1,415
  • 2
  • 19
  • 32

2 Answers2

2
decodeURI('\n') => newline; thus presumably

In your code, \n is a newline character before it even gets to decodeURI. Backslashes have meaning in a string literal in JavaScript.

decodeURI(decodeURI("\\n")) // => gives '\n' instead of newline

In this example, you've escaped the backslash with another backslash. Therefore, instead of passing a newline character to decodeURI(), you're passing the text of a backslash character and an 'n' character. Neither of these have special meaning in URIs and thus the output of this decodeURI() is the same as its input. Doing it twice of course makes zero difference. I don't really follow what your point is here.

But this does?

JSON.parse('"\\n"') // => newline

Again, try to unpack it is what you're doing here. The first backslash escapes the next, leaving you with an actual backslash in the string. So, the real string is "\n". If you JSON.parse() this, the parser first interprets that you're dealing with a string literal. Then, it decodes \n to a newline character. That's why it outputs just a newline.

Point here is to be able to build a * character string, then convert it to its actual character via decodeURI.

decodeURI has absolutely nothing to do with that.

Community
  • 1
  • 1
Brad
  • 159,648
  • 54
  • 349
  • 530
  • I get that decodeURI isn't meant for this and that I should use JSON.parse. I'm basically asking for the ability to build these escaped characters directly, without needing JSON.parse, which interprets it. – Karric Dec 17 '18 at 22:07
  • @Karric To re-emphasize what I wrote in my answer, a newline character has zero meaning to `decodeURI()`. If you want a newline out of `decodeURI()` (and, you shouldn't), just pass a newline into it, exactly as you do in your very first line of example code. I recommended reading up on some basic syntax of JavaScript and fully understanding this before proceeding. – Brad Dec 17 '18 at 22:09
1

There is a reason that this:

decodeURI(decodeURI("\\n"));

Doesn't give a newline, yet this does:

JSON.parse('"\\n"');

It's because \n is not actually a URI component (if a newline were URI encoded, it'd look like %0A rather than \n), and also because it's actually escaped.

Here are some demonstrations:


Demo 1: decodeURI("\n"):

var newline = decodeURI("\n");
console.log("Line One" + newline + "Line Two");

You can see in the above that there is a newline in the console, between Line One and Line Two.


Demo 2: decodeURI(decodeURI("\\n")):

var newline = decodeURI(decodeURI("\\n"));
console.log("Line One" + newline + "Line Two");

Here, we can see that the escaped newline (\\n) when decoded is just a newline string - newline literally is the string "\n", not a newline. We can see proof of this in the next demonstration:


Demo 3: typeof decodeURI("\\n"):

var newline = decodeURI("\\n");
console.log("Line One" + newline + "Line Two");
console.log(typeof newline);

And here we see that decodeURI("\\n") returns just a string \n, which for reasons unknown cannot be decoded by using decodeURI twice, as you'll see here:


Demo 4: decodeURI(decodeURI("\\n")):

var newline = decodeURI("\\n");
var temp = decodeURI(newline);
console.log("Line One" + newline + "Line Two");
newline = temp;
console.log("Line One" + newline + "Line Two");

And here we can see that newline and temp are pretty much the same thing - the string "\n".


There is a reason that this code:

decodeURI("\n");

Actually returns a newline character as well - it is because before decodeURI is used, "\n" is already a newline character, so decodeURI is redundant. See this:

var newlineString = "\n";
var newline = decodeURI(newlineString);
console.log("Line One" + newlineString + "Line Two");
console.log("Line One" + newline + "Line Two");

Here, both lines are separated by line breaks, which means that "\n" doesn't actually get decoded at all - you don't need decodeURI for this at all.


Hopefully this helps you!


Further reading:

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79