Reputation: 27
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.
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".
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
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
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
Reputation: 120486
There are a few separate issues here.
JavaScript has an instanceof
operator, and certain runtime values make sense to use on the right of instanceof
, so arguably, JavaScript has classes.
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.
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.
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