Kivylius
Kivylius

Reputation: 6547

Get all elements with specific prototype?

Let's take this example:

var Point = new function(){};

var Line = function(){};
    Line.prototype = new Point();

var line2 ....

I wan't to find all the entities that prototype Point. Some code I attempted but its not working:

for(key in window) {
  if(this[key] == Point){ // typeof is also not working.
     console.log(this[key]);
  }
}

Upvotes: 1

Views: 85

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1073968

If you change == in your example to instanceof, it will work for all global variables that have a Point object as their prototype:

for(key in window) {
  if(this[key] instanceof Point){ // <== using instanceof here
     console.log(this[key]);
  }
}

But you have an error in your definition of Point. You don't want new there, because later you use Point as a function. But new function() { } calls that anonymous function as a constructor and returns the non-function object created by new.

Complete working example: Live Copy | Live Source

var Point = function(){};

var Line = function(){};
    Line.prototype = new Point();

var lineInstance = new Line();
var pointInstance = new Point();

for(key in window) {
  if(window[key] instanceof Point){
     console.log(key + " is 'instanceof' Point");
  }
}

Notes on the above:

  • No new on the first line.

  • I actually create objects using new Point and new Line.

  • I've used window in both places in the loop. Using window in one place but this in another is just confusing (even though, in this case, they both refer to the same object).


If your goal is to find functions (line Line) that use a Point object as their prototype property (note that that property is not the prototype of any object, but it will become the prototype of objects created via those functions via new), then look at the prototype property: Live Copy | Live Source

for(key in window) {
  if(typeof window[key] === "function" &&
     window[key].prototype instanceof Point){
     console.log(key + " is a function using Point as its prototype property");
  }
}

I think the problem here may be that you're mistaking the concept of an object's prototype and the prototype property of functions, which are different but related things:

  • The prototype property of a function is just that: A property of the function.

  • When you create an object by calling a function via new (e.g., using it as a constructor function), one of the things that happens during the call using new is that a new object is created and is assigned its underlying prototype (which is not accessible as any property on the object*) from the constructor function's prototype property.

This is best explained with an example:

function Foo() {
}
Foo.prototype.bar = 42;

var f = new Foo();
console.log(f.bar); // "42"

The Foo function has a property called prototype. When we create a new object via new Foo, it gets its underlying prototype from Foo.prototype and so if we look up a property on that object and it doesn't have its own copy, the JavaScript engine looks at the prototype to see if it has one. And so the last line above works, logging "42" to the console.

(* I say above that the prototype underlying an object is not accessible as any property on the object. And that's true of JavaScript according to the standard. However, there is a non-standard extension that many engines provide, a property called __proto__, which is exactly that: The object's underlying prototype. But that's not standard. Within the standard, you can get an object's prototype by passing the object into Object.getPrototypeOf, which is new as of ES5.)


And finally: It is presumably just a throw-away example, but I wouldn't normally expect Line to inherit from Point, because there is no "is a" relationship (a Line is not a Point). The usual relationship here would be composition, not inheritance. A Line has Points, but a Line isn't a Point.

Upvotes: 5

Geeky Guy
Geeky Guy

Reputation: 9399

All elements will have different prototypes, because every element's prototype is a different instance of Point.

If you use the same prototype for them all, then you can compare. Otherwise, do as T.J. Crowder said and use instanceof.

Upvotes: 0

Related Questions