Check if object has method, without instantiating it - javascript

function object1(){
}
object1.prototype.myMethod = function(){};
function object2(){
this.myMethod = function(){};
}
I need to write an if statement that can check if any given object has the myMethod function, without creating an instance of said object. Is this possible?
This: testMe.prototype.hasOwnProperty('myMethod') would work only for object1, but for object2 will return false.
What is this for? I'm trying to emulate interfaces. I need to check if a function respects my interface before working on it and I want to leave the user total freedom on how this function is declared. Creating an instance of that function to check for it's properties sounds like opening a bottle with "water" written on it to check if there is water inside.

There is no way you can check if an object will have some instance methods without instantiating it, because you can add a new method anywhere:
var myObj= {};
...
if (myObj.newMethod) { //false
...
}
myObj.newMethod=function(){...};
if (myObj.newMethod) { //true
...
}

The second one isn't working without instantiating due to assigning this method on instantiating object, only. The code in body of function object2 is its "constructor" and it's run on instantiation only, obviously.

Related

Getting the Parent Function that Created an Instance

So this is a somewhat weird problem that may not be possible but I was wondering if it is possible to get a variable linkage of the function that created an instance from javascript.
for example, i'd like to be able to do something like this:
function MyObject(){
console.log(this) // traces out the instance
console.log(MyObject) // traces out the function
console.log(this.parentClass) //Would like this to trace out the function as well. (or a similar call like it)
}
var test = new MyObject();
Is this at all possible? Thanks!!
It's possible if the prototype objects on the functions haven't been replaced, or if the code replacing them keeps the linkage as it is by default.
The constructor property is (by default and convention) the property you're looking for:
var test = new MyObject();
console.log(test.constructor === MyObject); // "true"
Note all of the caveats above, though. For instance, this is perfectly valid (and not particularly atypical) code:
function MyObject() {
}
MyObject.prototype = {
foo: function() { /* ... */ },
bar: function() { /* ... */ }
};
This is a common pattern, although one I don't recommend. Instead of adding to the object referred to by the MyObject.prototype property (an object that was set up by the JavaScript engine when creating MyObject), that code is creating an entirely new object and assigning it to the prototype property, making it refer to the new object. If that has been done, then the constructor property has been broken, and you can't use it the way you want to use it.
The constructor property on the default prototype object on functions is a funny thing about JavaScript. It's defined quite clearly in the specification that it will be there (it's ยง13.2 if anyone wants to read up), but as far as I'm aware nothing in the JavaScript engine actually uses it. (It isn't, for instance, used for instanceof.)

How do I inherit a function from a base object and overwrite it in javascript

What I am trying to do is have a child object provide its own implementation for a function defined in a base object. As far as I've understood so far prototypes are the best (only!) way to go about doing this.
Note also that I am currently developing using the game engine: Turbulenz and as such I am trying to follow / stick to their style as closely as possible. In the engine "classes"/objects are defined and created in the following manner
function baseObject() { }
baseObject.prototype =
{
myMember1: 1,
myMember2: 2,
myMethod: function myMethodFn() {
return this.myMember1 + this.myMember2;
}
}
baseObject.Create = function baseObjectCreateFn
{
var o = new baseObject();
return o;
}
This would allow me to do the following
var anObject = baseObject.Create();
var someValue = anObject.myMethod(); // should return 3
What I would like to be able to do now is to create a new object that inherits all the properties of baseObject while allowing me to overwrite its myMethod function to for example subtract the two member values instead of add.
Would I be correct in saying that I will have to create another object then alter its prototype? The part thats throwing me most is that the definition of the baseObject's prototype is defined as an object literal and so I'm unsure of the syntax to overwrite one of its members, i.e. would the following be valid or not? :
function childObject() {}
childObject.prototype = baseObject.Create() // would this inherit from baseObject?
// or should it be: childObject.prototype = new baseObject();
// this is the part thats confusing me as the syntax
// doesn't quite match the original base objects prototype
// syntax and I'm unsure if that will matter
childObject.prototype.myMethod = function myMethodFn() {
return this.myMember1 - this.myMember2;
}
childObject.Create = function childObjectCreateFn
{
var o = new childObject();
return o;
}
var aChildObject = childObject.Create()
var anotherValue = aChildObject.myMethod() // would this return -1 as expected?
To summarise I'm trying to create an object that will overwrite a function that exists in a base object by inheriting the function from the base object and changing it, how do I do this? Thanks for your time.
You have it correct.
As for the syntax confusion, there is no real difference between
thing.prototype.myMethod = function () { ... }
and
thing.prototype = { myMethod: function() { ... } };
except for the fact that in the second one you are setting the prototype all at once (to an object literal), and if you do it again, you'll overwrite the prototype all at once with a new object literal. But because it is an object literal, you can't do inheritance this way (everything declared with naked braces { ... } is just an instance of Object of no special type). If you stick with the first syntax you'll always be ok.
Note that when you put:
childObject.prototype.myMethod = function myMethodFn() { ... }
The part where you put myMethodFn is actually ignored. The function is named myMethod by the fact that this is where you assigned it.
Similarly, where you have
childObject.Create = function childObjectCreateFn
you don't need childObjectCreateFn (it's ignored), and you need to put parentheses () somewhere after function or it's a syntax error.
Moving on to the reason why this works, every created object in Javascript has a prototype. When you call a method on that object, it first looks inside the object itself to see if a key corresponding to the name of the method exists. If not, it looks in the prototype object for the same thing, and if it's not there, it goes to that object's prototype, and so on, until it gets to the root Object, which has no prototype.
In this way you can override an implementation merely by naming it the same thing, but having it appear earlier in the prototype chain. That's exactly what you're doing on childObject. It retains the functionality of baseObject because you created an instance of baseObject to serve as childObject's prototype. Then you augmented childObject's prototype with a new method of the same name, but one that comes earlier in the prototype chain.

What object is being returned by .responseXML()?

I am trying to create a prototype/class that inherits from the object that is returned by a specific function. But I dont know what that object's name is?
For the instance var xhr = XMLHttpRequest(); what object is returned by xhr.responseXML;? Is it XMLDocument? Or maybe XMLDOM?
Also if I create the object var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); and call xmlDoc.load("xmlFile.xml" ); will it return the same type of object as xhr.responseXML;?
I am trying to do the following:
function XMLHandler()
{
this.xmlFile = "defaultXML.xml";
}
// Make XMLHandler inherit from Javascript object
XMLHandler.prototype = new XMLDocument();
XMLHandler.prototype.constructor = XMLDocument;
You shouldn't include unrelated questions in the same post. To address your second question about declaring a function within a "class":
Your first syntax, declaring it within the constructor, will pointlessesly overwrite myClass.prototype.publicFunct to point to a newly created function every time the constructor is called. That is, you will be creating an extra copy of the function with each call to the constructor, with myClass.prototype.publicFunct always pointing to the most recently created copy - or undefined until the constructor has been called at least once. Don't do this.
Your second option is simply invalid syntax in JavaScript.
Your third syntax is prefered. This will add the function to the prototype once.
Remember: JavaScript doesn't have classes as such, though you can sort of simulate them if you think it is worth the bother.
I can tell by your recent questions that you are thinking like Java, which this is not.
First question:
responseXML is different for each browser. Firefox gives a nsIDOMDocument, IE gives an IXMLDOMDocument and Webkit browsers depend on the responseType setting but will probably be Document. Since you cannot predict what it will be stop trying to extend it. In most cases the type isn't made available by the browser's API so javascript cannot extend it anyway.
Moreover, since JavaScript's inheritance is not class based you are forced into doing this:
XMLHandler.prototype = new XMLDocument();
...which simply does not work for your purpose. Any instance of XMLHandler will be built on an unrelated, empty document and not the document returned by responseXML. You have to use a wrapper here.
Second Question:
Of your 3 methods the first is equivalent to the last but more wasteful because it repeatedly sets the same function to the same prototype. The second is nonsensical, the syntax is broken. These are your real options:
// Instance method, every instance is given a copy of the function upon "new"
function MyClass()
{
this.publicFunct = function()
{
alert("public function");
};
}
// Prototypal method, only one copy of the function shared by all instances
function MyClass()
{
}
MyClass.prototype.publicFunct = function()
{
alert("public function");
};
// Shorthand method, same as prototypal but handy for several members at once
// It prevents MyClass from being a descendent of another type
function MyClass()
{
}
MyClass.prototype = {
// A colon is only acceptable in object notation
publicFunct: function()
{
alert("public function");
}
};
I would go with a prototypal method for efficiency unless you need to selectively add functions to a class. Your use of "public function" (also "class") seems like another symptom of an OOP background, there aren't any private functions in JavaScript so "public" has no place, all member functions are public. If at some point you do need a private function you can fake the effect with a closure.
(function() {
// Assignments are mostly global
MyClass = function() {};
MyClass.prototype.publicFunct = function()
{
privateFunct();
};
// These statements affect local scope
var foo = 'bar';
function privateFunct()
{
alert("public function");
}
})(); // These extra brackets cause the contents to be executed immediately
Having said that it is rare to need private functions and all JavaScript is visible anyway so it's not secret really. The above could be thwarted like this:
thief = {};
MyClass.prototype.publicFunct.call(thief);
// privateFunct is called by publicFunct in the context of the thief
You might as well accept that functions are public. You can go a step further and give up on classes altogether. Objects are just objects that happen to have some functions and those functions can even be shared with completely different objects.

How to retrieve the constructor's name in JavaScript?

Assume the following program:
var SomeConstructor = function() { };
var instance = = new SomeConstructor ();
The expression instance instanceof SomeConstructor yields True, so instance has to know somehow that it was constructed by the function SomeConstructor. Is there way to retrieve the name SomeConstructor directly from instance?
(In my problem at hand, I have a hierarchy of prototypes implementing possible signals in my application. I have to access the type of a signal which shall be equivalent to the constructor used to create that signal.)
On Chrome (7.0.544.0 dev), if I do:
function SomeConstructor() { }
var instance = new SomeConstructor();
console.log(instance.constructor.name);
it prints 'SomeConstructor'...but if SomeConstructor is defined as an unnamed function as you have it, it will print an empty string instead.
If I print instance.constructor it prints the same thing as it does if I print SomeConstructor in the code you have. The instanceof operator need only compare these two values to see that they are equal to be able to return true.
This code will get the name of the constructor, as long as it is not an anonymous function:
obj.constructor.toString().match(/function (\w*)/)[1];
Why would you need the class name? Let's say you want to save and restore class instances via JSON. You could store the class name in a "type" property, and then use a resolver function in JSON.parse to restore the objects. (See the sample code on this page).
So, in theory you could use the code above to make a generalized serializer that could handle any class instance, but parsing function strings is very inefficient. This overhead can be avoided by requiring all the classes you are going to store to provide the type explicitly:
function Foo() {}
Foo.prototype.type = 'Foo';
This seems silly and redundant, which is why I started on the quest to obtain the class name implicitly. But in the end I have to give in: there is no acceptable solution in JS :-(
No. You can use x.constructor to get a direct reference to C, but it's an anonymous function so there's no way of getting its name.
If it were defined like so:
function C() { };
x = new C();
Then it would be possible to use x.constructor.toString() and parse out the name of the function from the returned string. Some browsers would also support x.constructor.name[1].
[1] https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/name
You can also declare your class this:
var C = function C() { };
Now your C class constructor is a named function (no longer an anonymous function) meaning you can do:
x = new C();
console.log(x.constructor.name); // output: C
This code of yours that needs to know the constructor, can it access the constructor function itself? If so, you can just do that instanceof thing.
It seems that you need to know it by name. This sounds dangerous. Someone can create another constructor that happen to have the same name and it will pass (unless that's what you want, of course).
At least in React it might be
this.default.name

javascript find anonymous reference

I have this inside the HTML that is creating an object in JavaScript
var myObject = new MyClass();
I know that after this I can refer to myObject and use it.
The problem is that I have the instantiation done in an anonymous way e.g.
new MyClass()
Is there a way to find then the instance so I can reuse it later in the code ? Any idea appreciated.
for example
lastOfMe = null
function myClass() {
lastOfMe = this;
this.x = 123;
}
new myClass();
alert(lastOfMe.x)
this is totally ugly though
It depends of how MyClass works...
It could have saved all the instances in a class property, but in most cases, you must assign the result of the instantiation to a variable...
Anonymous objects are just that. If you want to use your object again, why create it anonymously?
If you really must do this, then just ensure that your object will register itself somewhere, like as a property of a global or similar, so you can grab it later.

Categories

Resources