Different behaviour of json.parse for same input? - javascript

This question is about
why the outputs are different
not how can i achieve the proper output.
I am unable to understand why the output of following two scenarios is not the same, even if I am giving the same argument to the JSON.parse() function.
FIRST scenario
obj = {a:"asdf"};
var newObj = JSON.parse(JSON.stringify(obj)); //newObj = {a:"asdf"}
Debugging
SECOND scenario
var newObj = JSON.parse("{"a":"asdf"}"); //this gives an error

The problem is with quotes.
var newObj = JSON.parse('{"a":"asdf"}');
should work correctly.
In Javascript, we use quotes (single or double) to represent a String. When you want to define a String that contains quotes, then you must use different quotes, or escape the quotes using backslash \ character.
var newObj = JSON.parse("{\"a\":\"asdf\"}");
also works fine.
You might think that
var newObj = JSON.parse("{'a':'asdf'}");
would work, but no. In JSON, strings are defined using Double quotes only.

why the outputs are different
Because the inputs are different.
FIRST scenario
obj = {a:"asdf"};
var newObj = JSON.parse(JSON.stringify(obj));
Here the input parameter of JSON.parse is JSON.stringify(obj)and this is a string that reads {"a":"asdf"}.
SECOND scenario
var newObj = JSON.parse("{"a":"asdf"}");
Here the input parameter of JSON.parse is a string that reads { and the rest is broken code.
Confusion arises because the console debugger decides all strings should be shown on the console encapsulated with a ", but this is just a way for the console to tell you that this value is of type String. It does not check whether you have " inside and escape them.
The encapsulating " are not part of the string, only a way of telling it is a string.
If console.logging JSON.stringify(obj) gets you "{"a":"asdf"}" try doing alert instead, or document.write. These will not add extra " and you will see that the value of JSON.stringify(obj) is actually {"a":"asdf"}, not "{"a":"asdf"}".
<html><head></head><body>
<script>
function JSONparse(string) {
document.write(string);
alert(string);
console.log(string);
return JSON.parse(string);
}
var obj = {a:"asdf"};
result = JSONparse(JSON.stringify(obj));
</script>
</body></html>

var newObj = JSON.parse('{"a":"asdf"}');

Related

How to eval string function and return value in javascript?

I have a method in string like:
var str = "function evalTest(param){if(param)return '<div>hello</div>'}else return '<div>world</div>'"
I am replacing param like:
var res = str.replace("param", "param=false");
Now if I do eval like:
var final = eval(res);
I am expecting final should contain result "world" because passed param = false.
How to achieve this result "world"?
First a caveat: There's almost certainly a better solution to whatever problem you're trying to solve by having that function in a string.
And another one: Never eval code supplied by an end user except for that same end user. For instance, never let user A supply the code, then eval it in user B's browser. (Without user B knowing that you're doing that and expressly consenting to it.)
Really, almost any time you're reaching for eval (or its cousin new Function), it's worth stepping back to see if there's another approach you can use.
But answering the question asked:
eval is just creating the function. You don't have anything in that string that calls it.
Because eval works magically in the current scope, evaling your string creates the function in the current scope. You could then call your function to get the result you're looking for:
var str = "function evalTest(param){if(param){return '<div>hello</div>'}else {return '<div>world</div>'}}";
var res = str.replace("param", "param=false");
eval(res);
var final = evalTest();
console.log(final);
Note that I fixed a couple of syntax errors in the function's text (curly brace issues, mostly).
If you don't want the function defined in the current scope, you can modify the string to make it a function expression and call it immediately:
var str = "function evalTest(param){if(param){return '<div>hello</div>'}else {return '<div>world</div>'}}";
var res = str.replace("param", "param=false");
var final = eval("(" + res + ")()");
console.log(final);

Console.log vs printing out variable

How come when I use console.log to print out a value in the console window for a string it is not in quotes, but when I just output the variable in the console, it prints quotes. Is there any particular reason for this?
var test = “hello”;
test;
Output : “hello”
Console.log(test);
Output: hello
Well , see like this.
var test = "hello";
test; // This is object in self and what is it,
// it is a string in literal
// Output comes only from debugger , when you input direct.
// test; this line have no output to the console
// Output : "hello" NO
//console.log(test); // console.log already print string (in native/string is output) but also print objects.
// Output: hello YES
console.log( test + " this is the test")
// See output it is a very clear
// hello this is the test
The default behavior is for strings to be represented along with quotes in the console.
a = 'hi';
a
// returns "hi"
The console api is different and an exception.
console.log(object [, object, ...])
Displays a message in the console. Pass one or more objects to this method. Each object is evaluated and concatenated into a space-delimited string.
So it returns a space-delimited, concatenated string. Which means it will always be a string. Since its always a string, we can do away with the quotes. I suppose the console devs let it be that way to make the point that console.log() will always return the same type (string). Adding quotes might imply the possibility that it could return other things, so it seems to be a UX thing for the console.
Javascript is dynamically typed which means a variable can store any type of value at any time. If you call a variable storing a string (which is test in your case) it prints out the value "Hello" indicating its a string and returns a string datatype, which is preety straightforward. But numbers can also be strings like var a = "5". On the other hand console.log() simply prints the value inside the variable and by default returns undefined.
var a = "hello";
// To check the return type of variable a which is string
console.log(typeof(a));
// To check the return type of console.log() which is undefined
console.log(typeof(console.log(a)));

Unable to capitalize the word in JS

I am trying to change the entire word into capital letters. What is wrong with my approach, for individual letters toUpperCase is working fine
var name = "gates";
for (var i=0; i< name.length; i++){
name[i] = name[i].toUpperCase();
}
name;
So the thing is "hello world".toUpperCase() is working fine as expected. Why the looping individual characters in array does not work as expected!.
Is this some property in arrays/strings especially in JS?
As RGraham mentioned the string letters cannot be modified, I don't understand the negative feedback of the community. Even the question seems to be valid.
The reason this doesn't work, is that accessing a string using the array syntax is read-only. As per the MDN docs:
For character access using bracket notation, attempting to delete or
assign a value to these properties will not succeed. The properties
involved are neither writable nor configurable. (See
Object.defineProperty() for more information.)
So, console.log(name[0]) will work, but name[0] = "G"; will not update the name variable.
You don't need to loop through the letters, just do:
var name = "gates";
name = name.toUpperCase();
A string is immutable in most languages, meaning, you can't change individual characters, or add something, without ending up with a new one.
name = name.toUpperCase();
Will give you what you need, but a new, all-caps string is put in the variable 'name'.
Accoring to http://www.w3schools.com/jsref/jsref_touppercase.asp
var str = "Hello World!";
var res = str.toUpperCase();
http://www.w3schools.com/jsref/jsref_touppercase.asp
var str = "Hello World!";
var res = str.toUpperCase();
Result:
HELLO WORLD!

Javascript: String concatenation in object constructor

Been trying to create a JavaScript object member that always contains a common string. Whenever I create a new object, instead of concatenating the string, it overwrites it with the passed value on creation. If it matters (I don't think it does) the string contains numbers. Par example:
function myObj(strToConcat){
this.combinedString = "Hello " + strToConcat, /* have used + and .concat() without success */
}
var newObj = new myObj("1.2.3");
console.log(newObj.combinedString); /* says "1.2.3", the leading "Hello " is absent */
Can't seem to get this to concatenate the strings.
EDIT: I apologize, the error was outside the code that I thought responsible. Disregard please. My apologies.
You have error in your reference
console.log(myObj.combinedString);
should be
console.log(newObj.combinedString);
Running your code gives me SyntaxError: Unexpected token }. Replace the , at the end of the second line with a ; and I get the expected result of "Hello 1.2.3".

accessing user input within the value of an object literal

These forums are amazing and the contributors I've been helped by are really talented. So I keep coming back everytime I can't solve my own problems or am not understanding a programming concept. This is certainly one of the latter times!
With the help I've received so far, I've managed to develop a complicated form in which the end user will mostly click a series of checkboxes and enter some data into a few textfields. The result of these actions will populate some textboxes with various text, based on the aforementioned actions.
The text that populates the textareas is referenced within a few object literals by each checkbox. This works just fine and the site is quite useable.
In my object literals, I have name:value pairs in which the 'value' is a string of text. I've been trying to include a variable within some name:value pairs to no success. This always breaks the script because the variable is never defined / has a 'null' value on page load.
For example,
Instead of
var example = {
var1:'some string',
var2:'some other string'
}
I tried,
var somevariable = document.getElementById('someId');
var example = {
var1: 'some string' + somevariable + 'some other bit',
var2: 'some other string'
}
My question is whether including a variable referenced elsewhere in the script can be incorporated within the name:value pair in an object literal?
For reference (and because it is a rather long script), my site is: http://www.hematogones.com/bmbiopsies.html.
The trick with an object literal is that it is evaluated immediately; there is no "easy" way to delay the value you get.
var x = "Alice";
var obj = { greeting: "Hello, " + x + "." };
console.log(obj.greeting); // "Hello, Alice."
x = "Bob";
console.log(obj.greeting); // "Hello, Alice."
obj = { greeting: "Hello, " + x + "." };
console.log(obj.greeting); // "Hello, Bob."
Something to come back to later:
If you really really really need to put a variable into a string literal you define later, you could create an inline function. This way, instead of obj.greeting being a simple string, it is a function that you call (which will look like obj.greeting()).This means that instead of the string value being calculated when you declare your object, it will be declared when you call the function. This is a very powerful feature of Javascript called "closures" and you could spend all day learning about the behaviors, expected and unexpected, that you get with them.
var x = "Alice";
var obj = { greeting: function() { return "Hello, " + x + "." }};
console.log(obj.greeting()); // "Hello, Alice."
x = "Bob";
console.log(obj.greeting()); // "Hello, Bob."
The short answer is yes. Here's a working example:
var myStr = "world";
var obj = { var1: "hello " + myStr };
console.log(obj.var1); // Outputs: hello world
As I mentioned in my comment, your specific example has a couple syntax errors, so perhaps just fixing those will correct your issue.

Categories