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

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"
}

Related

Using ".call" to create a new JavaScript object instead of "new"

I was trying the below commands on Chrome console. I am able to create the object using new(line 2 below) but using call doesn't work. Can anyone explain what could be the reason ?
function ObjConstructor(){ this.sample = 1};
let withNew = new ObjConstructor();
let usingCall = ObjConstructor.call({});
usingCall
undefined //output that came on console, this is not a command
withNew
ObjConstructor {sample: 1} //output that came on console
new does several things including:
Creating an object
Setting the this value to that object
Causes the function to return that object by default
Your code:
Creates an object manually with {}
Sets the this value to that object with call()
… but doesn't do the last thing. There is no return statement in the function, so it returns undefined.
The result of call is whatever the function returns. Your ObjConstructor doesn't return anything, so the result of calling it is undefined.
In contrast, when you use new, a new object is created and passed to the function, and unless the function returns a non-null object, the object created for new is the result of the new expression.
That's why the new version works but the call doesn't.
Also note that call doesn't create an object at all. In your ObjConstructor.call({}), what creates the object is {}, not call. It won't have ObjConstructor.prototype as its prototype. ({} is a raw object initializer, so the object will have Object.prototype as its prototype.)
try this.
Or look at this -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
var MyType = function(_param1,_param2){
this.param1 = _param1;
this.param2 = _param2;
this.ShowParam = function(){
alert(this.param1+" - "+this.param2);
}
}
var test = new MyType("PARAM TEST 1","PARAM TEST 2");
alert(test.param1+" - "+test.param2);
var test2 = new MyType("PARAM TEST 1.2","PARAM TEST 2.2");
alert(test2.param1+" - "+test2.param2);
test.ShowParam();
test2.ShowParam();

How change the object name that displays on console?

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 {}

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.

Making an object created by JSON.parse inherit from another class

I receive a bunch of objects via JSON which ultimately need to have some instance member functions.
Is there a way to do this without copying the data?
For example:
var DataObject = function() {};
DataObject.prototype.add = function() { return this.a + this.b; };
var obj = JSON.parse('{"a":1, "b":2}');
// Do something to obj to make it inherit from DataObject
console.assert( obj.add() === 3 );
I've tried setting obj.prototype = DataObject.prototype but that doesn't seem to work. What am I missing?
Well, in ECMAScript6 (in IE11, and every other non ie browser today), that would be __proto__
obj.__proto__ = Object.create(DataObject.prototype);
[fiddle]
Generally, make sure you only do this at the object creation case, otherwise it can be very risky to do.
Also note, setting the protoype explicitly is not always faster than copying two properties, as you can see here so you have to be sure there is actual gain here.

Get function name in JavaScript

Does anyone know if there is a way to get JavaScript function name. For example I got a function like
function test1(){
alert(1);
}
I have it in my head section. Then I create an object obj1 and put my function there
obj1.func = test1;
When I call a method in obj1 object, do I have any way to get my function name (test1) inside of this method, except parsing the source (this.func.toString()) of the function.
function test() { alert(arguments.callee.name); }
b = test;
b();
outputs "test" (in Chrome, Firefox and probably Safari). However, arguments.callee.name is only available from inside the function.
If you want to get name from outside you may parse it out of:
b.toString();
but I think name property of function object might be what you need:
alert(b.name);
this however does not seem work for IE and Opera so you are left with parsing it out manually in those browsers.
Until ES2015, there was no standard way to get the name of a function. Most current browsers support a name property on Function objects that was non-standard until ES2015, but no current version of IE does. The only option this leaves you if you need to support IE is trying to parse the name from the function's string representation, which is not a good idea. There's a (long) discussion here about it: http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/b85dfb2f2006c9f0
The best thing to do is:
function functionName(fun) {
var ret = fun.toString();
ret = ret.substr('function '.length);
ret = ret.substr(0, ret.indexOf('('));
return ret;
}
Note: Using Function.caller is non-standard and arguments.callee is forbidden in strict mode.
Here's what I use to put class names in error messages. It includes code to get the name of functions, which works in most browsers.
Obviously, there is no standard way that always works, so you should always provide a name that can be used if no other name is found.
var nameFromToStringRegex = /^function\s?([^\s(]*)/;
/**
* Gets the classname of an object or function if it can. Otherwise returns the provided default.
*
* Getting the name of a function is not a standard feature, so while this will work in many
* cases, it should not be relied upon except for informational messages (e.g. logging and Error
* messages).
*
* #private
*/
function className(object, defaultName) {
var result = "";
if (typeof object === 'function') {
result = object.name || object.toString().match(nameFromToStringRegex)[1];
} else if (typeof object.constructor === 'function') {
result = className(object.constructor, defaultName);
}
return result || defaultName;
}
This is probably the best way to do it:
var myfunc = function () {};
var funcName = myfunc.constructor.name;
This can be done outside the execution of the function, and you can check within the context of the browser console.
Happy coding!
One interesting way I'm experimenting with is a declaration like the following:
var test1 = function test1(){
alert(1);
};
It's a little hacky, but what ends up happening is test1 is a local variable that holds a [Function: test1] object.
Here's what happens when you use code based on it:
test1(); //runs the function as expected
console.log(test1.name); //prints 'test1'
So if you do the following:
obj1.func = test1;
You'll then be able to reference obj1.func.name and it'll return 'test1'.
You could convert your function into a string (fn + '') and split it later at whitespace and open bracket /\s|\(/.
var getFunctionName = function (fn) {
return (fn + '').split(/\s|\(/)[1];
};

Categories

Resources