user1384726
user1384726

Reputation: 27

Can I find the class name of a argument of the a function in javascript?

First part

The code:

function initGET(req, pre, cb){
    var urlparts = req.url.split('?');
    ...
}

Problem description:
suppose I do not know what is req/req.url and I want to find something more about it. I know definitely there is class which has a member called url. And maybe req is instance of that class, maybe req is instance of a class inherit that class.

Question:
Can I find the class name of req? Because req is of some class and inherit more classes. You have to define url member in some class.


Second part

Problem description:
Is there someway in javascript I could find that class, so I could go ahead to see the code or documentation?

for example,

var http1 = require('http');
func(http1), //is there a function? I could get "http".

Question:
is there a function? I could get "http".


Third part

Another example,

Problem description:

var server = http.createServer(function(req, res) { 
...}

http.createServer([requreListerner]) returns a new web server object.

The requestListener is a function which is atomaticaly added to 'request' event.

Event:'request'

function(request, responce) {}

request is an instance of http.IncomingMessage and response is an instance of http.ServerResponse.

Code:

    var server = http.createServer(function(req, res) { 
func(req) // is there a function? return http.IncomingMessage
func(res) // is there a function? return http.ServerResponse
...
});

Question:
is there a function? return http.IncomingMessage is there a function? return http.ServerResponse

Upvotes: 1

Views: 1075

Answers (3)

Sean Vieira
Sean Vieira

Reputation: 159865

Unfortunately, this part of your assumption:

Because req is of some class and inherit more classes. You have to define url member in some class.

is incorrect. Javascript doesn't have classes and there is no reason that req and res need to be classes to have members. req.constructor === Object && res.constructor === Object is perfectly legitimate. For example:

var req = {
  url: getUrlFromEnv()
};

var res = {
  body: function setBody(value) {
    // Write value to socket
  }
};

In the above example, both req and res are instances of Object, but they don't inherit from other classes. This is quite common in JS. Even if they do have their internal [[Prototype]] property set to point to another object there is no guarantee that that object is a "class":

var requestProto = {
    url: getUrlFromEnv()
};

var req = Object.create(requestProto);

Your best bet is Object.getPrototypeOf which will do the right thing in cases of inheritance, but will not help you in cases where new anonymous objects are being constructed that conform to a certain shape. (In such cases your only recourse is to read the source code where those objects are defined and everywhere in the call stack that has access to those objects since all objects are mutable by default).

Upvotes: 0

user128511
user128511

Reputation:

@Mike's answer is correct. Here's some code

// make a function (any function in JavaScript is a constructor)
function A() {}

// Make an instance of A
x = new A();

// print x's 'class'
console.log(x.constructor.name);
// prints "A"

// make another function
var B = function() {};

// make an instance of B
y = new B();

// print y's 'class'
y.constructor.name
// prints ""

So as you can see depending on how the class was made there's no guarantee you can find any name as their may be no name. You can use instanceof though it see if an object is one thing or another

console.log(x instanceof A);  // prints "true"
console.log(y instanceof A);  // prints "false
console.log(x instanceof B);  // prints "false
console.log(y instanceof B);  // prints "true

As @Mike points out, instanceof only works if you have a reference to the function that was passed to new which you often don't

Upvotes: 1

Mike Samuel
Mike Samuel

Reputation: 120486

There are a few separate issues here.

What is a class?

JavaScript has an instanceof operator, and certain runtime values make sense to use on the right of instanceof, so arguably, JavaScript has classes.

Type names

JavaScript does not have a nominal type system, so even though there might be classes, there is no such thing as a class name built into the language.

You could define a name as a dotted path of property names from the global object so that x != null && (typeof x == 'object') && (x instanceof eval(typeName(x)) is true. There are a number of problems with that though discussed below.

Name stability

For a name to be useful, it needs to address something. JavaScript does not attempt to guarantee name stability, and JavaScript programs often violate it.

For name stability to hold, you'd need

var localMyType = MyType;
...  // Program here
eval("MyType") === MyType  // Still true

unless the program does something really odd.

That's simply not the case.

There is no guarantee that any path of property lookups from the global object will arrive at the same constructor. JavaScript programs often violate this.

Name completeness

It's not uncommon for constuctors to be unreachable from the global object.

(function () {
  var instance;
  function Typ() {}

  (function () {
    var Typ = function () {};
    Typ.prototype.x = 1;
    instance = new Typ;
    alert(instance instanceof Typ);  // true
  })();

  alert(instance instanceof Typ);  // false     
}();

The type of instance is not reachable by any path of property lookups from the global objects, so any naming scheme layered on JS would not be complete.

The practice of wrapping modules in a closure envelope and then assigning the public interface to a global variables makes any types used as implementation details unnameable.

Upvotes: 2

Related Questions