Confusing p5.js Behaviour [duplicate] - javascript

In Safari with no add-ons (and actually most other browsers), console.log will show the object at the last state of execution, not at the state when console.log was called.
I have to clone the object just to output it via console.log to get the state of the object at that line.
Example:
var test = {a: true}
console.log(test); // {a: false}
test.a = false;
console.log(test); // {a: false}

I think you're looking for console.dir().
console.log() doesn't do what you want because it prints a reference to the object, and by the time you pop it open, it's changed. console.dir prints a directory of the properties in the object at the time you call it.
The JSON idea below is a good one; you could even go on to parse the JSON string and get a browsable object like what .dir() would give you:
console.log(JSON.parse(JSON.stringify(obj)));

What I usually do if I want to see it's state at the time it was logged is I just convert it to a JSON string.
console.log(JSON.stringify(a));

Vanilla JS:
#evan's answer seems best here. Just (ab)use JSON.parse/stringify to effectively make a copy of the object.
console.log(JSON.parse(JSON.stringify(test)));
JQuery specific solution:
You can create a snapshot of an object at a certain point in time with jQuery.extend
console.log($.extend({}, test));
What is actually happening here is jQuery is creating a new object with the test object's content, and logging that (so it will not change).
AngularJS (1) specific solution:
Angular provides a copy function that can be used to the same effect: angular.copy
console.log(angular.copy(test));
Vanilla JS wrapper function:
Here is an function which wraps console.log but will make a copy of any objects before logging them out.
I wrote this in response to a few similar but less robust functions in the answers. It supports multiple arguments, and will not try to copy things if they are not regular objects.
function consoleLogWithObjectCopy () {
var args = [].slice.call(arguments);
var argsWithObjectCopies = args.map(copyIfRegularObject)
return console.log.apply(console, argsWithObjectCopies)
}
function copyIfRegularObject (o) {
const isRegularObject = typeof o === 'object' && !(o instanceof RegExp)
return isRegularObject ? copyObject(o) : o
}
function copyObject (o) {
return JSON.parse(JSON.stringify(o))
}
example usage: consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})

That > Object in the console, isn't only showing the current state. It actually is deferring reading the object and it's properties until you expand it.
For example,
var test = {a: true}
console.log(test);
setTimeout(function () {
test.a = false;
console.log(test);
}, 4000);
Then expand the first call, it will be correct, if you do it before the second console.log returns

using Xeon06's hint, you may parse his JSON in an object, and here is the log function I now use to dump my objects :
function odump(o){
console.log($.parseJSON(JSON.stringify(o)));
}

There is an option to use a debugger library.
https://debugjs.net/
Just include the script into your web page and put log statements.
<script src="debug.js"></script>
Logging
var test = {a: true}
log(test); // {a: true}
test.a = false;
log(test); // {a: false}

I defined an utility:
function MyLog(text) {
console.log(JSON.stringify(text));
}
and when I want to log on console I simply do:
MyLog("hello console!");
It works very well!

You might want to log the object in a human readable way:
console.log(JSON.stringify(myObject, null, 2));
This indents the object with 2 spaces at each level.
How can I pretty-print JSON using JavaScript?

There's a new option as of late 2022:
Deep copy the object with the new DOM structuredClone method:
console.log(structuredClone(obj))
which uses the same cloning algorithm that's used to transfer messages between web workers.
This should be faster and work with more types of objects than the JSON.parse(JSON.stringify(obj)) technique.
See https://developer.mozilla.org/en-US/docs/Web/API/structuredClone for details.

I may be shot for suggesting this, but this can be taken one step further. We can directly extend the console object itself to make it more clear.
console.logObject = function(o) {
(JSON.stringify(o));
}
I don't know if this will cause some type of library collision/nuclear meltdown/rip in the spacetime continuum. But it works beautifully in my qUnit tests. :)

Simply refresh the page after you open the console or open the console before you submit the request to the targeted page....

Just print whole object on console.
console.log(object);

Related

Jquery .sort 2d object affects earlier variables (console.log before the sort returns also the sorted object) [duplicate]

In Safari with no add-ons (and actually most other browsers), console.log will show the object at the last state of execution, not at the state when console.log was called.
I have to clone the object just to output it via console.log to get the state of the object at that line.
Example:
var test = {a: true}
console.log(test); // {a: false}
test.a = false;
console.log(test); // {a: false}
I think you're looking for console.dir().
console.log() doesn't do what you want because it prints a reference to the object, and by the time you pop it open, it's changed. console.dir prints a directory of the properties in the object at the time you call it.
The JSON idea below is a good one; you could even go on to parse the JSON string and get a browsable object like what .dir() would give you:
console.log(JSON.parse(JSON.stringify(obj)));
What I usually do if I want to see it's state at the time it was logged is I just convert it to a JSON string.
console.log(JSON.stringify(a));
Vanilla JS:
#evan's answer seems best here. Just (ab)use JSON.parse/stringify to effectively make a copy of the object.
console.log(JSON.parse(JSON.stringify(test)));
JQuery specific solution:
You can create a snapshot of an object at a certain point in time with jQuery.extend
console.log($.extend({}, test));
What is actually happening here is jQuery is creating a new object with the test object's content, and logging that (so it will not change).
AngularJS (1) specific solution:
Angular provides a copy function that can be used to the same effect: angular.copy
console.log(angular.copy(test));
Vanilla JS wrapper function:
Here is an function which wraps console.log but will make a copy of any objects before logging them out.
I wrote this in response to a few similar but less robust functions in the answers. It supports multiple arguments, and will not try to copy things if they are not regular objects.
function consoleLogWithObjectCopy () {
var args = [].slice.call(arguments);
var argsWithObjectCopies = args.map(copyIfRegularObject)
return console.log.apply(console, argsWithObjectCopies)
}
function copyIfRegularObject (o) {
const isRegularObject = typeof o === 'object' && !(o instanceof RegExp)
return isRegularObject ? copyObject(o) : o
}
function copyObject (o) {
return JSON.parse(JSON.stringify(o))
}
example usage: consoleLogWithObjectCopy('obj', {foo: 'bar'}, 1, /abc/, {a: 1})
That > Object in the console, isn't only showing the current state. It actually is deferring reading the object and it's properties until you expand it.
For example,
var test = {a: true}
console.log(test);
setTimeout(function () {
test.a = false;
console.log(test);
}, 4000);
Then expand the first call, it will be correct, if you do it before the second console.log returns
using Xeon06's hint, you may parse his JSON in an object, and here is the log function I now use to dump my objects :
function odump(o){
console.log($.parseJSON(JSON.stringify(o)));
}
There is an option to use a debugger library.
https://debugjs.net/
Just include the script into your web page and put log statements.
<script src="debug.js"></script>
Logging
var test = {a: true}
log(test); // {a: true}
test.a = false;
log(test); // {a: false}
I defined an utility:
function MyLog(text) {
console.log(JSON.stringify(text));
}
and when I want to log on console I simply do:
MyLog("hello console!");
It works very well!
You might want to log the object in a human readable way:
console.log(JSON.stringify(myObject, null, 2));
This indents the object with 2 spaces at each level.
How can I pretty-print JSON using JavaScript?
There's a new option as of late 2022:
Deep copy the object with the new DOM structuredClone method:
console.log(structuredClone(obj))
which uses the same cloning algorithm that's used to transfer messages between web workers.
This should be faster and work with more types of objects than the JSON.parse(JSON.stringify(obj)) technique.
See https://developer.mozilla.org/en-US/docs/Web/API/structuredClone for details.
I may be shot for suggesting this, but this can be taken one step further. We can directly extend the console object itself to make it more clear.
console.logObject = function(o) {
(JSON.stringify(o));
}
I don't know if this will cause some type of library collision/nuclear meltdown/rip in the spacetime continuum. But it works beautifully in my qUnit tests. :)
Simply refresh the page after you open the console or open the console before you submit the request to the targeted page....
Just print whole object on console.
console.log(object);

Get a more useful value than "[object Object]" for debugging?

Couldn't there a be a environment flag in JavaScript so you could turn on some metadata for objects.
So instead when you are debugging and get:
[object Object]
you would get the variable name and type:
[foo String]
why isn't this possible?
JSON.stringify might be what you are looking for, though it won't give you the name of the variable – JavaScript simply can't do that without 3rd party tools.
The constructor function of your object can be reached by using its constructor property, though there's no guarantee with this as the constructor property is writable.
You might also want to look into the debugger statement.
A bit hacky , but it can help you to find what is your object source :
function Foo()
{}
var toClass = function(a)
{
var _name = a.constructor.toString().match(/^function (\w+)/i); //\w probably should be enhanced
console.log(_name[1])
}
toClass( new Foo()) //Foo
toClass( [1, 2]) //Array
toClass( new Date()) //Date
toClass( {"a":2}) //Object
Aside note : don't override toString just for debugging. toString has its purpose. and should be used as it was meant to be used.
To directly answer your question about just flipping a "global flag" instead of changing your debugging methodology:
Assuming you'd only do this during debugging, you can temporarily override the Object.prototype.toString to return a JSON representation of objects:
Object.prototype.toString = function () { return JSON.stringify(this); };
Then in the browser console:
var obj = { a: 42 };
console.log('My object: ' + obj);
Will give you:
My object: {"a":42}
Even if this answers your question, I don't recommend a global override of a base method because it has the potential to cause catastrophic issues. Try relying on unit tests and breakpoints + debugging as others have suggested in comments.

is there a way to refer to outputted object in dev console of chrome

Lot of times when I output an object in chrome using console.log(). It outputs the object and its properties in expandable tree format, which is nice. But is there a way to refer to it in console?...Like in console you can refer to Dom elements....as $0, $1, $2..etc.
Is there a way to refer to outputted objects so I can use them within in console by referring to them like: $c.obj1.someProperty..
This can be very useful when I am learning new Api, and debugging the object.
One approach would be to assign it to the window object under some property. Consider a function as follows:
function addDebugObject(obj) {
var index;
if (!window.debugObjects) {
window.debugObjects = [];
}
index = window.debugObjects.length;
window.debugObjects.push(obj);
console.log(index, obj);
}
Then to use it in the console
> addDebugObject({'d': 4})
0 [Object]
> obj = window.debugObjects[0]
{'d': 4}
You can refer to the last result using $_ (dollar-underscore).
(defined here)

javascript deep copy using JSON

I have problem with javascript object(array) deep copy. I read many good way to deal with it. And I also know that jQuery has $.extend API to this problem. But my question is: Can I just using JSON stringify and parse method to solve this problem?
Here's my code:
function deepCopy(oldValue) {
var newValue
strValue = JSON.stringify(oldValue)
return newValue = JSON.parse(strValue)
}
var a = {
b: 'b',
c: [1,2,4],
d: null
}
copy = deepCopy(a)
console.log(a === copy) // false
console.log(a.c === copy.c) // false
PS: I've known that if no all objects are serializable, but the only situation I know is that when the object contains a property which is function. Any other situation?
If your object is "small" and contains exclusively serializable properties, a simple deepCopy hack using JSON serialization should be OK. But, if your object is large, you could run into problems. And if it contains unserializable properties, those'll go missing:
var o = {
a: 1,
b: 2,
sum: function() { return a + b; }
};
var o2 = JSON.parse(JSON.stringify(o));
console.log(o2);
Yields:
Object {a: 1, b: 2}
Interestingly enough, a fair number of deep-copy solutions in C# are similar serialization/deserialization tricks.
Addendum: Not sure what you're hoping for in terms of comparing the objects after the copy. But, for complex objects, you generally need to write your own Compare() and/or Equals() method for an accurate comparison.
Also notable, this sort of copy doesn't preserve type information.
JSON.parse(JSON.stringify(new A())) instanceof A === false
You can do it that way, but it's problematic for some of the reasons listed above:
I question the performance.
Do you have any non-serializable properties?
And the biggest: your clone is missing type information. Depending upon what you're doing, that could be significant. Did the implementor add methods to the prototype of your original objects? Those are gone. I'm not sure what else you'll lose.
I think what you looking for is something like this:
If you have a really nested object structure then to make a deep copy you can make use of JSON.stringify().
Please see below example:
var obj= {
'a':1,
'b':2,
'c': {
'd':{
'e' : 3
}
}
}
var newObj = {...obj};
var lastObj = JSON.parse(JSON.stringify(obj));
obj.c.d.e =19;
console.log('obj '+obj.c.d.e);
console.log('newObj '+obj.c.d.e);
console.log('lastObj'+lastObj.c.d.e);
Now lastObj is truly detached from obj while if you use ...(spread) operator than also it does not work in really complex objects.
Hope this helps!!

Perform omit on the original object

I am very new to underscore js, I am trying to omit a certain property on an Object. What I did was
myObj = _.omit(myObj,name)
console.log(myObj);
Still the myObj seems to have the property name. Although if I do this it seemes to work
newMyObj= _.omit(myObj,name)
console.log (newMyObj)
it seemed to work fine. What am I doing wrong, can someone help? Ok, so myObj looks like this
Angola: "4.134137685",Brunei: "2.532726835",Countries: "2004",Croatia: "1.717672961", keys: Array[11]
I am trying to omit "keys" which again is an array of objects
Thanks
There are these things called "debuggers". If you don't know what they are, then stop everything you're doing and learn about them now. Search Google for "Chrome devtools", for instance. Stop your code (put a breakpoint) at the point before the call to _.omit. In the console, type in myObj to see exactly what it contains, then also name. Or, you could use the 'Scope Variables" section of devtools to check the value of these variables. Now, make a single step (F10). See if or how the variables have changed, or type myObj again into the console to check its value.
In your particular case, you report that the deletion of the property occurs properly when you do
newMyObj= _.omit(myObj,name)
but not with
myObj= _.omit(myObj,name)
In and of itself, that behavior is completely unexplainable. So there's something else going on that you're not telling us about. My guess is that you are doing something like this:
myObj = { keys: [] };
name = "keys";
delete_property();
console.log(myObj.keys); // []
function delete_property(myObj) {
myObj = _.omit (myObj, name);
}
However, this does not do what you might think. The assignment to myObj within the function does nothing; it just reassigns the value of the function argument. It has no effect on the myObj outside the function.
To be sure, we'd need to see more of your actual code, but this is just a regular old debugging problem of the sort you will encounter thousands of times in your programming career, so you're better off learning to solve it yourself.
I interpreted this question to mean you simply want to remove a property from an object using omit(). Note that omit() returns a copy of the object sans the specified property to remove. The method does not alter the object in place.
Given this premise, the code below, which matches what you have, works just fine:
var copy,
obj = {
Angola: "4.134137685",
Brunei: "2.532726835",
Countries: "2004",
Croatia: "1.717672961",
keys: Array[11]
},
check = function (o) {
_.each(o, function (value, key) {
console.log("key: " + key + " value: " + value);
});
};
copy = _.omit(obj, "keys");
check(copy);
obj = _.omit(obj, "keys");
check(obj);
You will get the same result whether you are using a new variable or the existing one.

Categories

Resources