0

Well, I am new to prototype programming / design. I would be happy for a help.

The question is why my "this.__proto__instances" inside "find" method returns "undefined"?

If my approach is wrong, forgive me, I will be happy to know the correct approach for calling a class method to find an element in a class variable array, without having the method to be defined for every child.

The problem in details is elaborated as comments in the code below.

Thank you.

function Attribute(name,type){
    //some members definition, including uid, name, and type
};

Attribute.prototype.find=function(uid){
    var found_attr=false;
    this.__proto__.instances.forEach(function(attr){ 
        if (attr.uid == uid) found_attr=attr;           
    }); 
    return found_attr;
};

this.__proto__.instances.forEach(function(attr){ above is the erroneous line. Log says "cannot call method forEach of undefined"

function ReferenceAttribute(arg_hash){
    Attribute.call(this,arg_hash.name,arg_hash.type); 
    //some members definition
    this.pushInstance(this); 
};

this.pushInstance(this); pushes this instance to ReferenceAttribute.prototype.instances that works fine

ReferenceAttribute.prototype=new Attribute(); 

ReferenceAttribute inherits Attribute with prototype chaining method

ReferenceAttribute.prototype.instances=new Array(); 

Line above declares array containing all instances of reference attributes. For every new object of ReferenceAttribute, it will be pushed into this array, done in a method pushInstance() . The pushing is always successful, I checked them via console logging. The array does contain the ReferenceAtribute instances

function ActiveAttribute(arg_hash){
    Attribute.call(this,arg_hash.name,arg_hash.type);
    //some members definition
    this.pushInstance(this); 
};

ActiveAttribute.prototype=new Attribute(); 
ActiveAttribute.prototype.instances=new Array(); 

use it in the program

var ref_attr=ReferenceAttribute.prototype.find("a uid"); 

gives the error saying that it cannot call method forEach of undefined. It can call method find, so it gets inherited well. But "this._proto_instances" inside find method definition is wrong I guess.

EDIT :

Attribute.prototype.pushInstance=function(my_attribute){    
    this.__proto__.instances.push(my_attribute);    
}; 

this function works. Although instances array is possessed by either ActiveAttribute or ReferenceAttribute, and not Attribute itself, but this function does work in pushing it to the array.

1
  • Thank you. I will make some edit Commented Oct 11, 2013 at 3:09

2 Answers 2

2

It's because you're doing this:

var ref_attr=ReferenceAttribute.prototype.find("a uid"); 

The ReferenceAttribute.prototype object is an instance created from the Attribute constructor, and Attribute.prototype has no .instances property, nor is there a .instances property defined directly on the object.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer. I appreciate it. I did some edit in the code. There is a pushInstance() method defined as a method of Attribute. It is called in the constructor of both children. And this method does work in pushing the instances to the Array. I do notice that the difference with "find()" is that pushInstance is called from a child's instance (object), while find() is called not from a child's object, but rather in a class context. What is your suggested approach for this?
Invoke it from an instance of ReferenceAttribute instead of from the constructor's prototype, so that it will reach that instance's Array. (new ReferenceAttribute).find("a uid")
2

user2736012 has your answer, so just a comment:

The __proto__ property is not standardised or supported by all browsers in use, so don't use it. Further, if you want to access properties of an an Object's [[Prototype]], use standard property resolution:

this.instances

If you're going to reference inherited methods directly, what's the point of inheritance?

6 Comments

Thank you for the advice. The solution by user2736012 works that I need to create a dummy instance of child attribute. Regarding your question above, my purpose is so that I do not need to define "find" method for every child. Say I have many children inheriting attribute, how could I write that method only once? My question is already resolved, but I will really be thankful if you have few minutes to help with advice.
Nevermind, I guess it is my fault to define instances array for every child, but wanted to have only 1 method to access them. It is an architectural flaw. Probably, you have a suggestion/page link that shows how I should have implemented them?
You just need to set this to the right object in the call, so if you call it as a method of an instance, you'll the the right instances array (per user2736012's comment).
Thanks..I guess I still need to learn how "this" works in more detail in javascript.
Most explanations on the web are not very good, so read a few and know that they are either wrong in some aspect or not clear. The best resource is ECMA-262, but it's a bit turgid. This article on MDN is pretty good.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.