Mankament Gra
Mankament Gra

Reputation: 147

Not working Object.create(Error.prototype)

i have code:

var TestError = function () {
var that = Error.call(this);
return that;
};
TestError.prototype = Object.create(Error.prototype);
TestError.prototype.why = function(){alert("NOT WORKING")}

var err = new TestError();
err.why();//not working :( TypeError: err.why is not a function

but not working :(

When I write

var TestError = function () {
var that = Error.call(this);
return that;
};
TestError.prototype = Error.prototype;
TestError.prototype.why = function(){alert("WORKING")}

var err = new TestError();
err.why();// working :( 

Why i cant use Object.create(Error.prototype)?

Upvotes: 2

Views: 224

Answers (1)

Felix Kling
Felix Kling

Reputation: 816364

The problem is not with Object.create. The problem is that you return that; from the constructor.

that is an instance of Error, not of TestError. So when you correctly add why to TestError.prototype, only instances of TestError will have that method, not Error.

This is roughly the state of the environment in your first example:

+--------------------+       +------------------------+        +-----------------+
|     TestError      |       |  TestError.prototype   | +----->| Error.prototype |
+------------+-------+       +-------------+----------+ |      +-----------------+
|  prototype |   *---+------>|     why     |<Function>| |               ^         
+------------+-------+       +-------------+----------+ |               |         
                             |[[Prototype]]|      *---+-+               |         
                             +-------------+----------+                 |         
                                                                        |         
                                                                        |         
                             +------------------------+                 |         
+--------------------+       |        <Object>        |                 |         
|        err         |------>+-------------+----------+                 |         
+--------------------+       |[[Prototype]]|     *----+-----------------+         
                             +-------------+----------+                           

Remove the line return that; and it will work.

var TestError = function() {
  Error.call(this);
};
TestError.prototype = Object.create(Error.prototype);
TestError.prototype.why = function() {
  alert("WORKING")
}

var err = new TestError();
err.why();

Because this is what you want:

+--------------------+       +------------------------+        +-----------------+
|     TestError      |       |  TestError.prototype   | +----->| Error.prototype |
+------------+-------+       +-------------+----------+ |      +-----------------+
|  prototype |   *---+------>|     why     |<Function>| |                         
+------------+-------+       +-------------+----------+ |                         
                             |[[Prototype]]|      *---+-+                         
                             +-------------+----------+                           
                                          ^                                       
                                          |                                       
                                          +---------------+                       
                                                          |                       
                             +------------------------+   |                       
+--------------------+       |        <Object>        |   |                       
|        err         |------>+-------------+----------+   |                       
+--------------------+       |[[Prototype]]|     *----+---+                       
                             +-------------+----------+                  

Why does it work without Object.create ? Because when you do

TestError.prototype = Error.prototype;

every extension you make to TestError.prototype extends Error.prototype. So when you add why, every instance of Error will have that method.

As I mentioned above, return that; returns an instance of Error. Since all error instances now have a why method, that works, but rather by accident, not by intentionally.

+--------------------+                                                 
|     TestError      |                       +------------------------+
+------------+-------+                       |    Error.prototype     |
|  prototype |   *---+---------------------->+-------------+----------+
+------------+-------+                       |     why     |<Function>|
                                             +-------------+----------+
                                                          ^            
                                                          |            
                                                          |            
                             +------------------------+   |            
+--------------------+       |        <Object>        |   |            
|        err         |------>+-------------+----------+   |            
+--------------------+       |[[Prototype]]|     *----+---+            
                             +-------------+----------+                

var TestError = function () {
var that = Error.call(this);
   return that;
};
TestError.prototype = Error.prototype;
TestError.prototype.why = function(){alert("WORKING")}

var err = new Error(); // <- Note that we execute Error here
err.why();// working, but it shouldn't. Every Error instance now has a why method

Upvotes: 4

Related Questions