Why does a concept of safe integer exists in JavaScript? - javascript

I have observed some weird stuff in native javascript on my chrome inspector console. For example, I ran this
var a = 10208629303283853;
var b = 10208629303283855;
console.log(a);
console.log(b);
which gives the result
10208629303283852
10208629303283856
Why there is a difference in value. On googling, I found that the above numbers are out of safe limit (refer to link below). That may cause it to behave abnormally. Why does a concept like this exists? and Why does var allows us to store the large number in the first place?
Source -- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER

Related

Storing different NaN value in variable

I figured there was nothing preventing code from storing a NaN-value different from the global NaN in a variable. However, i quickly experienced that this was dependent on the browser. Storing such a value in a variable worked just fine in Chrome (Version 67.0.3396.99 (Official Build) (64-bit)), while it did not in Firefox (61.0.1 (64-bit)).
Is behavior regarding this not clear from the spec, or does FF not fully follow it here? Why does FF convert the number to the value of the global NaN?
Here is a related snippet for testing:
let buffer = new ArrayBuffer(8);
let float = new Float64Array(buffer);
let bytes = new Uint8Array(buffer);
float[0] = NaN
bytes[0] = 1;
let differentNaN = float[0];
float[0] = differentNaN;
console.log(`We are ${bytes[0] === 0 ? "not" : "potentially"} on chrome!`);
6.1.6 The Number Type explains this fully:
[...] except that the 9007199254740990 (that is, 253-2) distinct
“Not-a-Number” values of the IEEE Standard are represented in
ECMAScript as a single special NaN value. (Note that the NaN value is
produced by the program expression NaN.) In some implementations,
external code might be able to detect a difference between various
Not-a-Number values, but such behaviour is implementation-dependent;
to ECMAScript code, all NaN values are indistinguishable from each
other.
along with the below
Note
The bit pattern that might be observed in an ArrayBuffer (see 24.1) or
a SharedArrayBuffer (see 24.2) after a Number value has been stored
into it is not necessarily the same as the internal representation of
that Number value used by the ECMAScript implementation.
I knew i had seen something like this in the spec before, but somehow didn't find it in my research before posting the question, and still took 40 minutes to find it after posting (i must be blind).

Object property value changes before code exectuion [duplicate]

I was helping a colleague debug some code today and I noticed a strange behavior with console.log() in Google Chrome:
It appears that if you:
Create a nested array (e.g., [[345,"test"]])
Log the array to the console with console.log().
Modify one of the inner array values, then console.log() will output the later value -- not the values of the array at the time the console.log() was executed.
JavaScript:
var test = [[2345235345,"test"]]
console.log(test);
test[0][0] = 1111111;
// outputs: [[1111111,"test"]]
var testb = {};
testb.test = "test";
console.log(testb);
testb.test = "sdfgsdfg";
// outputs: {"testb":"test"}
var testc = ["test","test2"];
console.log(testc);
testc[0] = "sdxfsdf";
// outputs: ["test","test2"]
JSFiddle Example
This behavior does not happen in Firefox.
Also to note, if I stepped through his code line by line in the Chrome debugger, then console.log() would output the correct values.
Is there an explanation for this strange phenomenon or is it just a bug with Google Chrome?
EDIT:
I've narrowed down the steps to reproduce the inconsistent console.log() behavior:
If you add this script to your page:
var greetings=['hi','bye'];
console.log(greetings);
setTimeout(function(){
greetings.push('goodbye');
},3000);
and open it in a new window with the Chrome console window already open, then the console.log() output will be different than if you load the page with the console window closed. Here's a JSFiddle that demonstrates that.
In the first case, with the console window already open, console.log() will output the current value of the array (i.e., two items).
In the second case, with the console window initially closed and opened only after the page loads, console.log() will output the later values of the array (i.e., three items).
Is this a bug in Google Chrome's console.log() functionality?
After a lot of digging, I found that this has been reported as a bug, fixed in Webkit, but apparently not yet pulled into Google Chrome.
As far as I can tell, the issue was originally reported here: https://bugs.webkit.org/show_bug.cgi?id=35801 :
Description From mitch kramer 2010-03-05 11:37:45 PST
1) create an object literal with one or more properties
2) console.log that object but leave it closed (don't expand it in the console)
3) change one of the properties to a new value
now open that console.log and you'll see it has the new value for some reason, even though it's value was different at the time it was generated.
I should point out that if you open it, it will retain the correct value if that wasn't clear.
Response from a Chromium developer:
Comment #2 From Pavel Feldman 2010-03-09 06:33:36 PST
I don't think we are ever going to fix this one. We can't clone object upon dumping it into the console and we also can't listen to the object properties' changes in order to make it always actual.
We should make sure existing behavior is expected though.
A fix was implemented two and a half years later on August 9th, 2012 for Webkit ( http://trac.webkit.org/changeset/125174 ), but it does not appear to have made it into Chrome yet.
As of today, dumping an object (array) into console will result in objects' properties being
read upon console object expansion (i.e. lazily). This means that dumping the same object while
mutating it will be hard to debug using the console.
This change starts generating abbreviated previews for objects / arrays at the moment of their
logging and passes this information along into the front-end. This only happens when the front-end
is already opened, it only works for console.log(), not live console interaction.
I found a workaround for this bug/feature.
console.log(JSON.parse(JSON.stringify(myObject)));
Edit: Unfortunately this won't work for non-primitive values like functions. Use another clone utility here.
jQuery example:
console.log($.extend({}, myObject));

Window object containing variable property before declaration (with value) [duplicate]

I was helping a colleague debug some code today and I noticed a strange behavior with console.log() in Google Chrome:
It appears that if you:
Create a nested array (e.g., [[345,"test"]])
Log the array to the console with console.log().
Modify one of the inner array values, then console.log() will output the later value -- not the values of the array at the time the console.log() was executed.
JavaScript:
var test = [[2345235345,"test"]]
console.log(test);
test[0][0] = 1111111;
// outputs: [[1111111,"test"]]
var testb = {};
testb.test = "test";
console.log(testb);
testb.test = "sdfgsdfg";
// outputs: {"testb":"test"}
var testc = ["test","test2"];
console.log(testc);
testc[0] = "sdxfsdf";
// outputs: ["test","test2"]
JSFiddle Example
This behavior does not happen in Firefox.
Also to note, if I stepped through his code line by line in the Chrome debugger, then console.log() would output the correct values.
Is there an explanation for this strange phenomenon or is it just a bug with Google Chrome?
EDIT:
I've narrowed down the steps to reproduce the inconsistent console.log() behavior:
If you add this script to your page:
var greetings=['hi','bye'];
console.log(greetings);
setTimeout(function(){
greetings.push('goodbye');
},3000);
and open it in a new window with the Chrome console window already open, then the console.log() output will be different than if you load the page with the console window closed. Here's a JSFiddle that demonstrates that.
In the first case, with the console window already open, console.log() will output the current value of the array (i.e., two items).
In the second case, with the console window initially closed and opened only after the page loads, console.log() will output the later values of the array (i.e., three items).
Is this a bug in Google Chrome's console.log() functionality?
After a lot of digging, I found that this has been reported as a bug, fixed in Webkit, but apparently not yet pulled into Google Chrome.
As far as I can tell, the issue was originally reported here: https://bugs.webkit.org/show_bug.cgi?id=35801 :
Description From mitch kramer 2010-03-05 11:37:45 PST
1) create an object literal with one or more properties
2) console.log that object but leave it closed (don't expand it in the console)
3) change one of the properties to a new value
now open that console.log and you'll see it has the new value for some reason, even though it's value was different at the time it was generated.
I should point out that if you open it, it will retain the correct value if that wasn't clear.
Response from a Chromium developer:
Comment #2 From Pavel Feldman 2010-03-09 06:33:36 PST
I don't think we are ever going to fix this one. We can't clone object upon dumping it into the console and we also can't listen to the object properties' changes in order to make it always actual.
We should make sure existing behavior is expected though.
A fix was implemented two and a half years later on August 9th, 2012 for Webkit ( http://trac.webkit.org/changeset/125174 ), but it does not appear to have made it into Chrome yet.
As of today, dumping an object (array) into console will result in objects' properties being
read upon console object expansion (i.e. lazily). This means that dumping the same object while
mutating it will be hard to debug using the console.
This change starts generating abbreviated previews for objects / arrays at the moment of their
logging and passes this information along into the front-end. This only happens when the front-end
is already opened, it only works for console.log(), not live console interaction.
I found a workaround for this bug/feature.
console.log(JSON.parse(JSON.stringify(myObject)));
Edit: Unfortunately this won't work for non-primitive values like functions. Use another clone utility here.
jQuery example:
console.log($.extend({}, myObject));

How does the console window handle JavaScript arithmetic assignment internally? Where is the returned value coming from?

I've been playing around with JavaScript a lot more lately, and this course I am going through keeps on emphasizing the importance of knowing JavaScript from within.
So I've got this kind of a weird question, it's mainly just me trying to understand how JavaScript works internally.
Let's say I do the following computation in the console:
>> x = 1
< 1
>> x = x + 2
< 3
The '3' that is being returned there, where is it coming from exactly?
Like is it evaluating 'x + 2' first, then returns 3 and sets the value of x in memory to 3? Or would it evaluate 'x + 2', save it in x's memory space, then return the value of x from that same memory space?
Or maybe even just alter x's value in its memory space without moving it around, then returns the value of x?
I would also appreciate any source on how I could learn more about the internal workings of JavaScript too, to answer more questions like these.
Thanks!
If you have ever worked on a terminal based system like Unix, it would be easier to understand what's going on. Think of the console a a type of bash terminal. If you type a command into a command line terminal and press the enter key the it will respond with an output or some times even an error.
Something similar is happening in the Chrome console. Every time you open a Chrome console it retains a session where it stores your variables and functions. And when you call or use the same variable or function it is simply returning that value.
BTW when you type something like
>> x = 1
what happens internally is the that a new property called x in created in the global window object. So x = 1 is same as window.x = 1. This is how the console can remember you assignments and use it later when you call it.
I hope I managed to confuse you, so I will stop here.
You can take your example further to see its logic like
>> x = 1
< 1
>> y = x = x + 2
< 3
>> x == y
< true
It is basically output of the line. Some features you have seen on your browser are implemented on top of Javascript engine. Here is my favorite talk slightly related to the topic.

Google Chrome console.log() inconsistency with objects and arrays

I was helping a colleague debug some code today and I noticed a strange behavior with console.log() in Google Chrome:
It appears that if you:
Create a nested array (e.g., [[345,"test"]])
Log the array to the console with console.log().
Modify one of the inner array values, then console.log() will output the later value -- not the values of the array at the time the console.log() was executed.
JavaScript:
var test = [[2345235345,"test"]]
console.log(test);
test[0][0] = 1111111;
// outputs: [[1111111,"test"]]
var testb = {};
testb.test = "test";
console.log(testb);
testb.test = "sdfgsdfg";
// outputs: {"testb":"test"}
var testc = ["test","test2"];
console.log(testc);
testc[0] = "sdxfsdf";
// outputs: ["test","test2"]
JSFiddle Example
This behavior does not happen in Firefox.
Also to note, if I stepped through his code line by line in the Chrome debugger, then console.log() would output the correct values.
Is there an explanation for this strange phenomenon or is it just a bug with Google Chrome?
EDIT:
I've narrowed down the steps to reproduce the inconsistent console.log() behavior:
If you add this script to your page:
var greetings=['hi','bye'];
console.log(greetings);
setTimeout(function(){
greetings.push('goodbye');
},3000);
and open it in a new window with the Chrome console window already open, then the console.log() output will be different than if you load the page with the console window closed. Here's a JSFiddle that demonstrates that.
In the first case, with the console window already open, console.log() will output the current value of the array (i.e., two items).
In the second case, with the console window initially closed and opened only after the page loads, console.log() will output the later values of the array (i.e., three items).
Is this a bug in Google Chrome's console.log() functionality?
After a lot of digging, I found that this has been reported as a bug, fixed in Webkit, but apparently not yet pulled into Google Chrome.
As far as I can tell, the issue was originally reported here: https://bugs.webkit.org/show_bug.cgi?id=35801 :
Description From mitch kramer 2010-03-05 11:37:45 PST
1) create an object literal with one or more properties
2) console.log that object but leave it closed (don't expand it in the console)
3) change one of the properties to a new value
now open that console.log and you'll see it has the new value for some reason, even though it's value was different at the time it was generated.
I should point out that if you open it, it will retain the correct value if that wasn't clear.
Response from a Chromium developer:
Comment #2 From Pavel Feldman 2010-03-09 06:33:36 PST
I don't think we are ever going to fix this one. We can't clone object upon dumping it into the console and we also can't listen to the object properties' changes in order to make it always actual.
We should make sure existing behavior is expected though.
A fix was implemented two and a half years later on August 9th, 2012 for Webkit ( http://trac.webkit.org/changeset/125174 ), but it does not appear to have made it into Chrome yet.
As of today, dumping an object (array) into console will result in objects' properties being
read upon console object expansion (i.e. lazily). This means that dumping the same object while
mutating it will be hard to debug using the console.
This change starts generating abbreviated previews for objects / arrays at the moment of their
logging and passes this information along into the front-end. This only happens when the front-end
is already opened, it only works for console.log(), not live console interaction.
I found a workaround for this bug/feature.
console.log(JSON.parse(JSON.stringify(myObject)));
Edit: Unfortunately this won't work for non-primitive values like functions. Use another clone utility here.
jQuery example:
console.log($.extend({}, myObject));

Categories

Resources