4

I created two function A and B. Made A as prototype of B. jsfiddle

function A(){

}

function  B(){
    this.name ="Class B";
}

B.prototype = A;
var b = new B();
alert(b.name); // expected Class B got A

I know I should have used B.prototype = new A();

Is above behavior expected? Is it possible to get "Class B" instead of "A" in above scenario?

Note: I am using above because A has some property associated with it as A.text = "Text" A.text1 = "Text2" and I want these property available to B. so B.prototype == A.prototype. can not be used.

Anoop
  • 23,044
  • 10
  • 62
  • 76
  • `B.prototype = A;` is assigning the function `A` to the prototype of `B`, that's probably _not_ what you want. – elclanrs Nov 22 '12 at 22:38
  • That scenario seems irrelevant since you'd probably never want to do that, but yes, you can get `"Class B"` in implementations that don't support the non-standard `.name` property on functions. – I Hate Lazy Nov 22 '12 at 22:40
  • ...though it does seem odd that you couldn't assign a property since `this` is the object, not the prototype. – I Hate Lazy Nov 22 '12 at 22:42

2 Answers2

2

Have a look at the possible duplicate What is the reason to use the 'new' keyword at Derived.prototype = new Base and also at this answer on why there are no "classes" in javascript.

Yes, the behaviour is expected. B.prototype, the object from which your b instance inherits, is the function object A. So, it does inherit its name property which is the string "A".

And, this property is immutable (its property descriptor is {configurable: false, enumerable: false, value: "B", writable: false}), so when you try to assign a new value to b.name, this will check for [[CanPut]] which returns false - and nothing happens. in strict mode, an Invalid assignment in strict mode TypeError would be thrown (demo).

You only could overwrite it using Object.defineProperty.


@Edit: I'm not sure why you want those properties inherited by B. They are "static attributes" of the A constructor function and they should stay there. There is currently no way to let a Function inherit from anything else than Function.prototype, so either you go with copying them or your don't use them. Tell us for what you'd need them, and we can find a solution.

Changing the prototype property of functions (and objects in general) does not make them happen to inherit from anything else. The prototype property of functions points to the object from which newly created (constructed) instances will inherit.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Ah - and that property is not mutable. Durr. I've been scratching my head for a couple of minutes now. – Pointy Nov 22 '12 at 22:38
  • The point is that the inherited `"name"` property is non-writable, so the attempt to create an own property with that name fails. – Šime Vidas Nov 22 '12 at 22:45
  • I just wanted to know why prototype property is given more preference than own property? – Anoop Nov 22 '12 at 22:48
  • @ŠimeVidas As for I know if you create an object which have same prototype name as its prototype. You can access both property using __proto__ and directly accessing by property name. That means there are tow layer. in above case name "A" is property of prototype. why is it not allowing instance of B to have its own property. ? – Anoop Nov 22 '12 at 23:00
  • 1
    @Sushil Well, read my comments in the other answers. If the inherited property is non-writable, you cannot shadow it by simple assignment. The "name" property of the `A` function is non-writable, so `this.name = ...` inside `B` fails. – Šime Vidas Nov 22 '12 at 23:07
  • 1
    @Sushil the deal is this: when you mention `name` in an expression, the runtime first has to determine whether `name` is a symbol that's already defined. In this case, it **is** defined, and it's defined as a non-mutable property of the prototype. Thus, the assignment statement does nothing at all. – Pointy Nov 23 '12 at 00:08
0

If you want B to "inherit" from A, write:

B.prototype = Object.create( A.prototype );
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Do you understand why the code as written behaves the way it does? I'm confused by it; maybe I'm just tired :-) – Pointy Nov 22 '12 at 22:37
  • Explain why that's better than `new A`, what the drawbacks are and I'll give you an upvote :-) – Bergi Nov 22 '12 at 22:41
  • @Pointy It appears that it's not possible to shadow an inherited `"name"` property, if it belongs to a function: http://jsfiddle.net/hG64d/1/ I'm not sure why, I'll have to investigate. – Šime Vidas Nov 22 '12 at 22:41
  • http://jsperf.com/object-create-vs-constructor-vs-object-literal/7 indicates that using new is faster than object.create – sroes Nov 22 '12 at 22:51
  • 1
    @SanderRoesink Those options are not the same. The first two create an object which inherits from `Object.prototype`, whereas the last one creates an object which inherits from `Obj.prototype`, which in turn inherits from `Object.prototype`. – Šime Vidas Nov 22 '12 at 22:56