How change the object name that displays on console? - javascript

I really want to know if this is possible?
The circled object is generated by jQuery, and its with the custom name.
Please advise, how can I name a object like that. Thank you very much!!!
var obj = [{ a : 1 , b : 2 }]
console.log (obj)
Can you give me an example that you can change the object name to "Foo" with above object and simple with console.log

You need to override the toString method.
A very shorthand example:
console.log( ""+{toString:()=>'My Object'} );
// prints: My Object
How?
toString is called whenever the object in question is demanded in context of a string value. This happens when you're appending to a string or forcing the conversion with the toString() method.
If you have classes, you can do it as a prototype:
function MyClass () { /*...*/ }
MyClass.prototype.toString =()=> 'Not MyClass';
Whether the effect is seen in object traversal depends on when or if toString will be called. Otherwise it may be browser specific.
Using Browser / Traversal views
This worked in Chrome:
var x = {};
x.y = function(){};
console.log(new x.y); // prints: x.y {}
It relies on the source code where the function was created. Note no function name! If I had, this is what would happen:
var x = {};
x.y = function X (){};
console.log(new x.y); // prints: X {}

Related

Getting undefined for methods defined as properties using new Object()

i just tried the following way of having a function assigned for a object. It works on chrome(43.0) but does not work on firefox(36.0.4)
code:
var obj = new Object();
obj.name = "Andrew";
obj.age = 20;
obj.print = function(){
console.log( this.name );
console.log( this.age );
}
obj.print(); // printing undefined in Firefox
I know of other ways of adding a function to an object such as Object.getPrototypeOf() and Object.defineProperty() but those are for json objects i suppose. The code sample above uses the object constructor, i want to know how to add a method to an object created with the object constructor. If its just not possible to have methods in an object created with the object constructor, let me know of that too. I know how to use JSON and get the methods within it or use call and apply, this is just for finding out if there is a way to add a method for objects using the new Object() constructor.
Thank you.
In firefox the function prints out "Andrew" and "20" as you'd expect.
It does also print out undefined but thats just because you function has no return value.
it's nothing to worry about, firefox is just letting you know, chrome isnt because it wont cause any issues.
if it something that worries you, have the function return true
obj.print = function(){
console.log( this.name );
console.log( this.age );
return true;
}
it will now show true in firefox instead of undefined
Also make sure that you have Log tunred on in your dev tools log level, if Log is ruened off, you'll only see the undefined messages.
Have you tried declaring the object like this? :
var obj = {
name : "Andrew",
age : "20"
}

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.

A function to tap into any methods chain

I like how Ruby's .tap method works. It lets you tap into any method chain without breaking the chain. I lets you operate an object then returns the object so that the methods chain can go on as normal. For example if you have foo = "foobar".upcase.reverse, you can do:
"foo = foobar".upcase.tap{|s| print s}.reverse
It will print the upcased (but not reversed) string and proceed with the reversing and assignment just like the original line.
I would like to have a similar function in JS that would serve a single purpose: log the object to console.
I tried this:
Object.prototype.foo = function() {
console.log(this);
return this;
};
Generally, it works (though it outputs Number objects for numbers rather than their numeric values).
But when i use some jQuery along with this, it breaks jQuery and stops all further code execution on the page.
Errors are like this:
Uncaught TypeError: Object foo has no method 'push'
Uncaught TypeError: Object function () { window.runnerWindow.proxyConsole.log( "foo" ); } has no method 'exec'
Here's a test case: http://jsbin.com/oFUvehAR/2/edit (uncomment the first line to see it break).
So i guess that it's not safe to mess with objects' prototypes.
Then, what is the correct way to do what i want? A function that logs current object to console and returns the object so that the chain can continue. For primitives, it should log their values rather than just objects.
You correctly figured out how a method can be safely added anywhere in a chain, but your adding it to the Object.prototype is intrusive and can break code easily. Looks like jQuery code is the one that breaks for you.
A much safer way is:
Object.defineProperty(Object.prototype, 'foo', {
value : function() { console.log( "foo" ); return this; },
enumerable : false
});
DEMO: http://jsbin.com/oFUvehAR/7/edit
Finally, something generic could look like this:
Object.defineProperty(Object.prototype, 'tap', {
value : function(intercept) {
intercept.call(this);
return this;
},
enumerable : false
});
// Usage:
var x = { a:1 };
x.tap(function(){ console.log(this); });
As for the primitives part of your question, that is a bit trickier. When you call the tap method on a primitive, an Object wrapper is created and the tap method is called on it. The primitive value is still available, via the valueOf() method of that Object wrapper, so you could log it. The tricky part is that you have no way of knowing if the "thing" that you wanted to call the tap method on was initially a primitive or an Object wrapper. Assuming you never want to work with Object wrappers (that is quite reasonable), you could do the better tap method posted below.
Object.defineProperty(Object.prototype, 'tap', {
value : function(intercept) {
var val = (this instanceof Number || this instanceof String || this instanceof Boolean) ? this.valueOf() : this;
intercept(val);
return val;
},
enumerable : false
});
var log = console.log.bind(console);
var x = { a : 1 };
x.tap(log);
2.0.tap(log);
Notice that while in the first version of the tap function, the function passed to it had the useful information in this, in the second version it is mandatory to pass it as a parameter.
If you want a specialized logger for it, you can do something like this:
Object.defineProperty(Object.prototype, 'log', {
value : function(){
return this.tap(console.log.bind(console));
},
enumerable : false,
writable : true /* You want to allow objects to overwrite the log method */
});

How can I get exactly what .this is pointing to

Is there a way to get the exact name of the object that this is referring to and not just object Object?
No there is not. An object in javascript doesn't inherently have a name. Instead it has a set of named references which point to it (or possibly none). The this value is just one of these references.
// The {} is an object without a name. Here 'x' is a reference
// to that object
var x = {};
// Now 'y' refers to the same object as 'x'. But neither 'x'
// nor 'y' is the name of the object.
var y = x;
No, but you can see what this is at any given time by dumping to the console:
console.log(this);
You could try something like this, even though it will not work in some cases:
function R3S (){
this.a = function(){
whoIs(this);
}
}
function whoIs(obj) {
console.log(/(\w+)\(/.exec(obj.constructor.toString())[1]);
}
var t = new R3S();
whoIs(t);
t.a();
var l = t;
l.a();
Hope this helps.
Maybe you would want to take a look at this post also : How to get class object's name as a string in Javascript?
"this" is also just another alias to your object, there could be many variable names pointing to the same this as "this" points to. There is no known way to get the original name the object was created with(if any). The best you could get is the type of "this"
Object.prototype.toString.call(this)

JavaScript Object

I can easily create and object in a lot of different. For example like this:
var myObject = {
myFunction: function () {
return "";
}
};
So if I alert this object I get something this:
[object Object]
Now I'm if I alert the NaN object I get this:
NaN
And I can still call function from it:
alert(NaN.hasOwnProperty().toString());
So my question is how can I create a object like the NaN object?
If I alert it, it should return something like myObject
I should be able to create and call functions on it like myObject.myFunction();
function MyObject(){}
MyObject.prototype = {
toString: function(){
return "myObject";
},
myFunction: function(){
}
};
var myObject = new MyObject();
alert( myObject );
//myObject
Only objects that are created using a constructor function get their class name displayed using console.log(), as shown in #Esalijia's answer.
Even then, it'll be the class name that's displayed, not the name of whatever variable you happened to assign the object to.
Adding a toString() method to the object will however change the output of the alert() function, since that always looks for the presence of that method and use it if it exists.
So, writing:
var myObj = {
toString: function() { return "boo"; }
}
alert(myObj)
will show boo in the alert box, instead of [Object object].
alert(NaN.hasOwnProperty().toString()); // says false.
alert(typeof NaN); //says it is a number
So, I don't think NaN is an Object and It's datatype is a number.
For more info: NaN means Not-a-Number. Even datatype is number, it is not a number. When any mathematical calculation can't return number,it returns NaN. The isNaN() function determines whether a value is an illegal number (Not-a-Number).This function returns true if the value is NaN, and false if not.
For example,
var num=35;
var num2=num/'asg';
console.log(num2); //returns NaN
NaN is a number primitive, not an object. Like all primitives, it is converted to an object when you use the . operator to access a property or method that exists on the creator class's prototype.
To display properties available for primitives, either convert them to an object, or use console.dir()
console.dir(NaN);
console.log(Object(NaN));
All primitives behave this way, when you call console.log on any of the following, they exhibit the same behaviour:
console.log("Hello");
console.log(1);
console.log(true);
Yet, you can access properties on them like normal objects:
"Hello".length;
1 .toString();
true.valueOf();

Categories

Resources