Is function a 'Function' object in JavaScript? if so, when I create a constructor function like:
//this is a constructor function
function foo(){
this.name="xx";
}
Does foo has a property named proto pointing to the Function's prototype? How can I see this property?
ps: If proto is created when an instance is created via the new keyword, why does not function foo have it? According to above, foo is created via new Function.
1 Answer 1
is function a object in javascript?
Yes.
Does foo has a property named proto pointing to the Function 's prototype?
Not named proto, no. This is a bit of a confusing area:
All objects have an underlying prototype object they inherit from. From ES5 onward, you can get a reference to that object via
Object.getPrototypeOf(e.g.,var p = Object.getPrototypeOf(blah)gives you a reference toblah's prototype). Some engines (including Firefox's SpiderMonkey) also make underlying prototype available via the pseudo-property__proto__, and that will be in the spec as of ES6, but officially only when JavaScript is used in browsers.Separately, all normal functions have a property called
prototype, which is not that function's underyling prototype (see above). Instead, it's the object that will get assigned as the underlying prototype of objects created using that function as a constructor via thenewkeyword.
Since this is a bit confusing, let's draw a picture. Suppose we have this code:
function Foo() {
this.name = "xx";
}
var f = new Foo();
(Since I used it as a constructor, I've used the name Foo rather than foo to stick to conventions.)
Here's what we now have in memory:
+------------+ | Function | | (function) | +------------+ +-----------+ | __proto__ |----+->| (object) | This is the object assigned to functions | prototype |----/ +-----------+ as their underyling prototype +------------+ | | call | | | apply | | | bind | | | ... | | +-----------+ +------------+ | | Foo | | | (function) | | +------------+ | | __proto__ |----+ | | +----------+ | prototype |----+---->| (object) | This is the object assigned to +------------+ | +----------+ objects created via `new Foo` | | (blank) | | +----------+ +-----------+ | | f | | | (object) | | +-----------+ | | __proto__ |-----+ | name: xx | +-----------+
(I've left off the references to Object.property above to keep things simpler.)
How can I see this property.
See above, either __proto__ (on only some engines for now, will be standard in ES6) or via Object.getPrototypeOf (ES5).
Example:
// Shows you the object referenced by Function.prototype,
// which is `foo`'s underyling prototype
// ONLY WORKS ON SOME ENGINES for now (including Firefox's SpiderMonkey)
console.log(foo.__proto__);
// Shows you the object referenced by foo.prototype
console.log(foo.prototype);
8 Comments
Function.prototype points to. I've added a diagram to the answer to help clarify, and expanded on __proto__ vs. prototype.__proto__ ... will be standard as of ES6" deserves some qualification. __proto__ is included in the ES 6 Draft for browsers only, probably only because it has been implemented in some browsers. Mozilla invented it, deprecated it, now tolerates it under sufferance. Object.getPrototypeOf is the recommended method that persists in ES 6. Your answer suggests that it is ES5 only and not in ES 6.getPrototypeOf was going away, but I've reworded anyway. Hopefully no ambiguity now.
String.sliceis undefined, butString.prototype.sliceis the same exact same function as"".slice()and is also the same function asnew String("hello").constructor.prototype.slice. it is a little funny at first, but the "new " operator essentially puts anything the constructor's prototype defines into virtual properties on the resulting instance.__proto__and.constructor.prototypeare of limited utility in efficiently-written applications.obj.constructor.prototypewill have no effect onobjat all; but it will change what happens the next time that constructor function is used...)